* [PATCH AUTOSEL 4.14 094/170] selftests/bpf: use __bpf_constant_htons in test_prog.c
From: Sasha Levin @ 2019-01-28 16:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Stanislav Fomichev, Daniel Borkmann, Alexei Starovoitov,
Sasha Levin, netdev, linux-kselftest
In-Reply-To: <20190128161200.55107-1-sashal@kernel.org>
From: Stanislav Fomichev <sdf@google.com>
[ Upstream commit a0517a0f7ef23550b4484c37e2b9c2d32abebf64 ]
For some reason, my older GCC (< 4.8) isn't smart enough to optimize the
!__builtin_constant_p() branch in bpf_htons, I see:
error: implicit declaration of function '__builtin_bswap16'
Let's use __bpf_constant_htons as suggested by Daniel Borkmann.
I tried to use simple htons, but it produces the following:
test_progs.c:54:17: error: braced-group within expression allowed only
inside a function
.eth.h_proto = htons(ETH_P_IP),
Signed-off-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/bpf/test_progs.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
index 11ee25cea227..1903fb4f45d8 100644
--- a/tools/testing/selftests/bpf/test_progs.c
+++ b/tools/testing/selftests/bpf/test_progs.c
@@ -43,10 +43,10 @@ static struct {
struct iphdr iph;
struct tcphdr tcp;
} __packed pkt_v4 = {
- .eth.h_proto = bpf_htons(ETH_P_IP),
+ .eth.h_proto = __bpf_constant_htons(ETH_P_IP),
.iph.ihl = 5,
.iph.protocol = 6,
- .iph.tot_len = bpf_htons(MAGIC_BYTES),
+ .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES),
.tcp.urg_ptr = 123,
};
@@ -56,9 +56,9 @@ static struct {
struct ipv6hdr iph;
struct tcphdr tcp;
} __packed pkt_v6 = {
- .eth.h_proto = bpf_htons(ETH_P_IPV6),
+ .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6),
.iph.nexthdr = 6,
- .iph.payload_len = bpf_htons(MAGIC_BYTES),
+ .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES),
.tcp.urg_ptr = 123,
};
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.14 114/170] mac80211: fix radiotap vendor presence bitmap handling
From: Sasha Levin @ 2019-01-28 16:11 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Johannes Berg, Luca Coelho, Sasha Levin, linux-wireless, netdev
In-Reply-To: <20190128161200.55107-1-sashal@kernel.org>
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit efc38dd7d5fa5c8cdd0c917c5d00947aa0539443 ]
Due to the alignment handling, it actually matters where in the code
we add the 4 bytes for the presence bitmap to the length; the first
field is the timestamp with 8 byte alignment so we need to add the
space for the extra vendor namespace presence bitmap *before* we do
any alignment for the fields.
Move the presence bitmap length accounting to the right place to fix
the alignment for the data properly.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/rx.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 9e19ddbcb06e..c7ac1a480b1d 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -141,6 +141,9 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local,
/* allocate extra bitmaps */
if (status->chains)
len += 4 * hweight8(status->chains);
+ /* vendor presence bitmap */
+ if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA)
+ len += 4;
if (ieee80211_have_rx_timestamp(status)) {
len = ALIGN(len, 8);
@@ -182,8 +185,6 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local,
if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA) {
struct ieee80211_vendor_radiotap *rtap = (void *)skb->data;
- /* vendor presence bitmap */
- len += 4;
/* alignment for fixed 6-byte vendor data header */
len = ALIGN(len, 2);
/* vendor data header */
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.14 116/170] Bluetooth: Fix unnecessary error message for HCI request completion
From: Sasha Levin @ 2019-01-28 16:11 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Johan Hedberg, Marcel Holtmann, Sasha Levin, linux-bluetooth,
netdev
In-Reply-To: <20190128161200.55107-1-sashal@kernel.org>
From: Johan Hedberg <johan.hedberg@intel.com>
[ Upstream commit 1629db9c75342325868243d6bca5853017d91cf8 ]
In case a command which completes in Command Status was sent using the
hci_cmd_send-family of APIs there would be a misleading error in the
hci_get_cmd_complete function, since the code would be trying to fetch
the Command Complete parameters when there are none.
Avoid the misleading error and silently bail out from the function in
case the received event is a command status.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/hci_event.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 01f211e31f47..363dc85bbc5c 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -5212,6 +5212,12 @@ static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
return true;
}
+ /* Check if request ended in Command Status - no way to retreive
+ * any extra parameters in this case.
+ */
+ if (hdr->evt == HCI_EV_CMD_STATUS)
+ return false;
+
if (hdr->evt != HCI_EV_CMD_COMPLETE) {
BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
return false;
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.14 117/170] mlxsw: spectrum: Properly cleanup LAG uppers when removing port from LAG
From: Sasha Levin @ 2019-01-28 16:11 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Ido Schimmel, David S . Miller, Sasha Levin, netdev
In-Reply-To: <20190128161200.55107-1-sashal@kernel.org>
From: Ido Schimmel <idosch@mellanox.com>
[ Upstream commit be2d6f421f680e01d58f7cd452646e0d8586d49b ]
When a LAG device or a VLAN device on top of it is enslaved to a bridge,
the driver propagates the CHANGEUPPER event to the LAG's slaves.
This causes each physical port to increase the reference count of the
internal representation of the bridge port by calling
mlxsw_sp_port_bridge_join().
However, when a port is removed from a LAG, the corresponding leave()
function is not called and the reference count is not decremented. This
leads to ugly hacks such as mlxsw_sp_bridge_port_should_destroy() that
try to understand if the bridge port should be destroyed even when its
reference count is not 0.
Instead, make sure that when a port is unlinked from a LAG it would see
the same events as if the LAG (or its uppers) were unlinked from a
bridge.
The above is achieved by walking the LAG's uppers when a port is
unlinked and calling mlxsw_sp_port_bridge_leave() for each upper that is
enslaved to a bridge.
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/mellanox/mlxsw/spectrum.c | 23 ++++++++++++++++
.../mellanox/mlxsw/spectrum_switchdev.c | 27 +------------------
2 files changed, 24 insertions(+), 26 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index cf65b2ee8b95..7892e6b8d2e8 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -3907,6 +3907,25 @@ void mlxsw_sp_port_dev_put(struct mlxsw_sp_port *mlxsw_sp_port)
dev_put(mlxsw_sp_port->dev);
}
+static void
+mlxsw_sp_port_lag_uppers_cleanup(struct mlxsw_sp_port *mlxsw_sp_port,
+ struct net_device *lag_dev)
+{
+ struct net_device *br_dev = netdev_master_upper_dev_get(lag_dev);
+ struct net_device *upper_dev;
+ struct list_head *iter;
+
+ if (netif_is_bridge_port(lag_dev))
+ mlxsw_sp_port_bridge_leave(mlxsw_sp_port, lag_dev, br_dev);
+
+ netdev_for_each_upper_dev_rcu(lag_dev, upper_dev, iter) {
+ if (!netif_is_bridge_port(upper_dev))
+ continue;
+ br_dev = netdev_master_upper_dev_get(upper_dev);
+ mlxsw_sp_port_bridge_leave(mlxsw_sp_port, upper_dev, br_dev);
+ }
+}
+
static int mlxsw_sp_lag_create(struct mlxsw_sp *mlxsw_sp, u16 lag_id)
{
char sldr_pl[MLXSW_REG_SLDR_LEN];
@@ -4094,6 +4113,10 @@ static void mlxsw_sp_port_lag_leave(struct mlxsw_sp_port *mlxsw_sp_port,
/* Any VLANs configured on the port are no longer valid */
mlxsw_sp_port_vlan_flush(mlxsw_sp_port);
+ /* Make the LAG and its directly linked uppers leave bridges they
+ * are memeber in
+ */
+ mlxsw_sp_port_lag_uppers_cleanup(mlxsw_sp_port, lag_dev);
if (lag->ref_count == 1)
mlxsw_sp_lag_destroy(mlxsw_sp, lag_id);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 9052e93e1925..f33fb95c4189 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -291,30 +291,6 @@ mlxsw_sp_bridge_port_destroy(struct mlxsw_sp_bridge_port *bridge_port)
kfree(bridge_port);
}
-static bool
-mlxsw_sp_bridge_port_should_destroy(const struct mlxsw_sp_bridge_port *
- bridge_port)
-{
- struct net_device *dev = bridge_port->dev;
- struct mlxsw_sp *mlxsw_sp;
-
- if (is_vlan_dev(dev))
- mlxsw_sp = mlxsw_sp_lower_get(vlan_dev_real_dev(dev));
- else
- mlxsw_sp = mlxsw_sp_lower_get(dev);
-
- /* In case ports were pulled from out of a bridged LAG, then
- * it's possible the reference count isn't zero, yet the bridge
- * port should be destroyed, as it's no longer an upper of ours.
- */
- if (!mlxsw_sp && list_empty(&bridge_port->vlans_list))
- return true;
- else if (bridge_port->ref_count == 0)
- return true;
- else
- return false;
-}
-
static struct mlxsw_sp_bridge_port *
mlxsw_sp_bridge_port_get(struct mlxsw_sp_bridge *bridge,
struct net_device *brport_dev)
@@ -352,8 +328,7 @@ static void mlxsw_sp_bridge_port_put(struct mlxsw_sp_bridge *bridge,
{
struct mlxsw_sp_bridge_device *bridge_device;
- bridge_port->ref_count--;
- if (!mlxsw_sp_bridge_port_should_destroy(bridge_port))
+ if (--bridge_port->ref_count != 0)
return;
bridge_device = bridge_port->bridge_device;
mlxsw_sp_bridge_port_destroy(bridge_port);
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.14 121/170] cw1200: Fix concurrency use-after-free bugs in cw1200_hw_scan()
From: Sasha Levin @ 2019-01-28 16:11 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Jia-Ju Bai, Kalle Valo, Sasha Levin, linux-wireless, netdev
In-Reply-To: <20190128161200.55107-1-sashal@kernel.org>
From: Jia-Ju Bai <baijiaju1990@gmail.com>
[ Upstream commit 4f68ef64cd7feb1220232bd8f501d8aad340a099 ]
The function cw1200_bss_info_changed() and cw1200_hw_scan() can be
concurrently executed.
The two functions both access a possible shared variable "frame.skb".
This shared variable is freed by dev_kfree_skb() in cw1200_upload_beacon(),
which is called by cw1200_bss_info_changed(). The free operation is
protected by a mutex lock "priv->conf_mutex" in cw1200_bss_info_changed().
In cw1200_hw_scan(), this shared variable is accessed without the
protection of the mutex lock "priv->conf_mutex".
Thus, concurrency use-after-free bugs may occur.
To fix these bugs, the original calls to mutex_lock(&priv->conf_mutex) and
mutex_unlock(&priv->conf_mutex) are moved to the places, which can
protect the accesses to the shared variable.
Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/st/cw1200/scan.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/st/cw1200/scan.c b/drivers/net/wireless/st/cw1200/scan.c
index cc2ce60f4f09..f22c8ae15ad8 100644
--- a/drivers/net/wireless/st/cw1200/scan.c
+++ b/drivers/net/wireless/st/cw1200/scan.c
@@ -78,6 +78,10 @@ int cw1200_hw_scan(struct ieee80211_hw *hw,
if (req->n_ssids > WSM_SCAN_MAX_NUM_OF_SSIDS)
return -EINVAL;
+ /* will be unlocked in cw1200_scan_work() */
+ down(&priv->scan.lock);
+ mutex_lock(&priv->conf_mutex);
+
frame.skb = ieee80211_probereq_get(hw, priv->vif->addr, NULL, 0,
req->ie_len);
if (!frame.skb)
@@ -86,19 +90,15 @@ int cw1200_hw_scan(struct ieee80211_hw *hw,
if (req->ie_len)
skb_put_data(frame.skb, req->ie, req->ie_len);
- /* will be unlocked in cw1200_scan_work() */
- down(&priv->scan.lock);
- mutex_lock(&priv->conf_mutex);
-
ret = wsm_set_template_frame(priv, &frame);
if (!ret) {
/* Host want to be the probe responder. */
ret = wsm_set_probe_responder(priv, true);
}
if (ret) {
+ dev_kfree_skb(frame.skb);
mutex_unlock(&priv->conf_mutex);
up(&priv->scan.lock);
- dev_kfree_skb(frame.skb);
return ret;
}
@@ -120,10 +120,9 @@ int cw1200_hw_scan(struct ieee80211_hw *hw,
++priv->scan.n_ssids;
}
- mutex_unlock(&priv->conf_mutex);
-
if (frame.skb)
dev_kfree_skb(frame.skb);
+ mutex_unlock(&priv->conf_mutex);
queue_work(priv->workqueue, &priv->scan.work);
return 0;
}
--
2.19.1
^ permalink raw reply related
* Re: TCP/IPv4 sending using MSG_ZEROCOPY and closing the socket
From: Willem de Bruijn @ 2019-01-28 16:54 UTC (permalink / raw)
To: mathias_koehrer; +Cc: Network Development, Willem de Bruijn
In-Reply-To: <a31edb71e344445e24a4e0e5325ae315@arcor.de>
On Mon, Jan 28, 2019 at 2:57 AM <mathias_koehrer@arcor.de> wrote:
>
> Hi all,
>
> I have one question on the behavior of TCP/IPv4 sending using the MSG_ZEROCOPY flag,
> the kernel version is 4.19.18.
>
> What happens if I close the sending socket immediately after performing a socket
> send() or sendmsg() call (called with the MSG_ZEROCOPY flag)?
> I.e. in this situation not all messages have been sent yet, however - as the
> socket is closed - it is no longer possible to retrieve the completion
> notification via the error channel.
>
> Is it fine for the user space program to free all outstanding messages after the
> socket close() has returned?
> Or is there anything else that has to be considered?
If closing the socket while user memory is still in transmission, it
will not be possible to safely reuse the memory, as the process has no
way of discovering when the kernel has finished transmission.
Depending on type of memory, there may be workarounds to avoid
unbound virtual memory growth, such as unmapping the virtual
address range in the case of mmap()ed data.
But in general, the right approach is to wait for all completions
before closing a socket.
If this takes a long time, say due to the TCP stack hold on to data for
retransmission in the case a peer does not properly close its side,
disconnect (connect() AF_UNSPEC) can be used to purge the
queues and trigger notifications. Again, this is a last resort and
usually not needed.
^ permalink raw reply
* [PATCH bpf-next v3 3/3] selftests/bpf: add simple BPF_PROG_TEST_RUN examples for flow dissector
From: Stanislav Fomichev @ 2019-01-28 16:53 UTC (permalink / raw)
To: netdev; +Cc: davem, ast, daniel, Stanislav Fomichev
In-Reply-To: <20190128165355.229403-1-sdf@google.com>
Use existing pkt_v4 and pkt_v6 to make sure flow_keys are what we want.
Also, add new bpf_flow_load routine (and flow_dissector_load.h header)
that loads bpf_flow.o program and does all required setup.
Signed-off-by: Stanislav Fomichev <sdf@google.com>
---
tools/testing/selftests/bpf/Makefile | 3 +
.../selftests/bpf/flow_dissector_load.c | 43 ++--------
.../selftests/bpf/flow_dissector_load.h | 55 +++++++++++++
tools/testing/selftests/bpf/test_progs.c | 78 ++++++++++++++++++-
4 files changed, 139 insertions(+), 40 deletions(-)
create mode 100644 tools/testing/selftests/bpf/flow_dissector_load.h
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 89b0d1799ff3..c566090e5657 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -148,6 +148,9 @@ $(OUTPUT)/test_xdp_noinline.o: CLANG_FLAGS += -fno-inline
$(OUTPUT)/test_queue_map.o: test_queue_stack_map.h
$(OUTPUT)/test_stack_map.o: test_queue_stack_map.h
+$(OUTPUT)/flow_dissector_load.o: flow_dissector_load.h
+$(OUTPUT)/test_progs.o: flow_dissector_load.h
+
BTF_LLC_PROBE := $(shell $(LLC) -march=bpf -mattr=help 2>&1 | grep dwarfris)
BTF_PAHOLE_PROBE := $(shell $(BTF_PAHOLE) --help 2>&1 | grep BTF)
BTF_OBJCOPY_PROBE := $(shell $(LLVM_OBJCOPY) --help 2>&1 | grep -i 'usage.*llvm')
diff --git a/tools/testing/selftests/bpf/flow_dissector_load.c b/tools/testing/selftests/bpf/flow_dissector_load.c
index ae8180b11d5f..77cafa66d048 100644
--- a/tools/testing/selftests/bpf/flow_dissector_load.c
+++ b/tools/testing/selftests/bpf/flow_dissector_load.c
@@ -12,6 +12,7 @@
#include <bpf/libbpf.h>
#include "bpf_rlimit.h"
+#include "flow_dissector_load.h"
const char *cfg_pin_path = "/sys/fs/bpf/flow_dissector";
const char *cfg_map_name = "jmp_table";
@@ -21,46 +22,13 @@ char *cfg_path_name;
static void load_and_attach_program(void)
{
- struct bpf_program *prog, *main_prog;
- struct bpf_map *prog_array;
- int i, fd, prog_fd, ret;
+ int prog_fd, ret;
struct bpf_object *obj;
- int prog_array_fd;
- ret = bpf_prog_load(cfg_path_name, BPF_PROG_TYPE_FLOW_DISSECTOR, &obj,
- &prog_fd);
+ ret = bpf_flow_load(&obj, cfg_path_name, cfg_section_name,
+ cfg_map_name, &prog_fd);
if (ret)
- error(1, 0, "bpf_prog_load %s", cfg_path_name);
-
- main_prog = bpf_object__find_program_by_title(obj, cfg_section_name);
- if (!main_prog)
- error(1, 0, "bpf_object__find_program_by_title %s",
- cfg_section_name);
-
- prog_fd = bpf_program__fd(main_prog);
- if (prog_fd < 0)
- error(1, 0, "bpf_program__fd");
-
- prog_array = bpf_object__find_map_by_name(obj, cfg_map_name);
- if (!prog_array)
- error(1, 0, "bpf_object__find_map_by_name %s", cfg_map_name);
-
- prog_array_fd = bpf_map__fd(prog_array);
- if (prog_array_fd < 0)
- error(1, 0, "bpf_map__fd %s", cfg_map_name);
-
- i = 0;
- bpf_object__for_each_program(prog, obj) {
- fd = bpf_program__fd(prog);
- if (fd < 0)
- error(1, 0, "bpf_program__fd");
-
- if (fd != prog_fd) {
- printf("%d: %s\n", i, bpf_program__title(prog, false));
- bpf_map_update_elem(prog_array_fd, &i, &fd, BPF_ANY);
- ++i;
- }
- }
+ error(1, 0, "bpf_flow_load %s", cfg_path_name);
ret = bpf_prog_attach(prog_fd, 0 /* Ignore */, BPF_FLOW_DISSECTOR, 0);
if (ret)
@@ -69,7 +37,6 @@ static void load_and_attach_program(void)
ret = bpf_object__pin(obj, cfg_pin_path);
if (ret)
error(1, 0, "bpf_object__pin %s", cfg_pin_path);
-
}
static void detach_program(void)
diff --git a/tools/testing/selftests/bpf/flow_dissector_load.h b/tools/testing/selftests/bpf/flow_dissector_load.h
new file mode 100644
index 000000000000..41dd6959feb0
--- /dev/null
+++ b/tools/testing/selftests/bpf/flow_dissector_load.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+#ifndef FLOW_DISSECTOR_LOAD
+#define FLOW_DISSECTOR_LOAD
+
+#include <bpf/bpf.h>
+#include <bpf/libbpf.h>
+
+static inline int bpf_flow_load(struct bpf_object **obj,
+ const char *path,
+ const char *section_name,
+ const char *map_name,
+ int *prog_fd)
+{
+ struct bpf_program *prog, *main_prog;
+ struct bpf_map *prog_array;
+ int prog_array_fd;
+ int ret, fd, i;
+
+ ret = bpf_prog_load(path, BPF_PROG_TYPE_FLOW_DISSECTOR, obj,
+ prog_fd);
+ if (ret)
+ return ret;
+
+ main_prog = bpf_object__find_program_by_title(*obj, section_name);
+ if (!main_prog)
+ return ret;
+
+ *prog_fd = bpf_program__fd(main_prog);
+ if (*prog_fd < 0)
+ return ret;
+
+ prog_array = bpf_object__find_map_by_name(*obj, map_name);
+ if (!prog_array)
+ return ret;
+
+ prog_array_fd = bpf_map__fd(prog_array);
+ if (prog_array_fd < 0)
+ return ret;
+
+ i = 0;
+ bpf_object__for_each_program(prog, *obj) {
+ fd = bpf_program__fd(prog);
+ if (fd < 0)
+ return fd;
+
+ if (fd != *prog_fd) {
+ bpf_map_update_elem(prog_array_fd, &i, &fd, BPF_ANY);
+ ++i;
+ }
+ }
+
+ return 0;
+}
+
+#endif /* FLOW_DISSECTOR_LOAD */
diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
index 126fc624290d..5f46680d4ad4 100644
--- a/tools/testing/selftests/bpf/test_progs.c
+++ b/tools/testing/selftests/bpf/test_progs.c
@@ -39,6 +39,7 @@ typedef __u16 __sum16;
#include "bpf_endian.h"
#include "bpf_rlimit.h"
#include "trace_helpers.h"
+#include "flow_dissector_load.h"
static int error_cnt, pass_cnt;
static bool jit_enabled;
@@ -53,9 +54,10 @@ static struct {
} __packed pkt_v4 = {
.eth.h_proto = __bpf_constant_htons(ETH_P_IP),
.iph.ihl = 5,
- .iph.protocol = 6,
+ .iph.protocol = IPPROTO_TCP,
.iph.tot_len = __bpf_constant_htons(MAGIC_BYTES),
.tcp.urg_ptr = 123,
+ .tcp.doff = 5,
};
/* ipv6 test vector */
@@ -65,9 +67,10 @@ static struct {
struct tcphdr tcp;
} __packed pkt_v6 = {
.eth.h_proto = __bpf_constant_htons(ETH_P_IPV6),
- .iph.nexthdr = 6,
+ .iph.nexthdr = IPPROTO_TCP,
.iph.payload_len = __bpf_constant_htons(MAGIC_BYTES),
.tcp.urg_ptr = 123,
+ .tcp.doff = 5,
};
#define _CHECK(condition, tag, duration, format...) ({ \
@@ -1882,6 +1885,76 @@ static void test_queue_stack_map(int type)
bpf_object__close(obj);
}
+#define CHECK_FLOW_KEYS(desc, got, expected) \
+ CHECK(memcmp(&got, &expected, sizeof(got)) != 0, \
+ desc, \
+ "nhoff=%u/%u " \
+ "thoff=%u/%u " \
+ "addr_proto=0x%x/0x%x " \
+ "is_frag=%u/%u " \
+ "is_first_frag=%u/%u " \
+ "is_encap=%u/%u " \
+ "n_proto=0x%x/0x%x " \
+ "sport=%u/%u " \
+ "dport=%u/%u\n", \
+ got.nhoff, expected.nhoff, \
+ got.thoff, expected.thoff, \
+ got.addr_proto, expected.addr_proto, \
+ got.is_frag, expected.is_frag, \
+ got.is_first_frag, expected.is_first_frag, \
+ got.is_encap, expected.is_encap, \
+ got.n_proto, expected.n_proto, \
+ got.sport, expected.sport, \
+ got.dport, expected.dport)
+
+static struct bpf_flow_keys pkt_v4_flow_keys = {
+ .nhoff = 0,
+ .thoff = sizeof(struct iphdr),
+ .addr_proto = ETH_P_IP,
+ .ip_proto = IPPROTO_TCP,
+ .n_proto = bpf_htons(ETH_P_IP),
+};
+
+static struct bpf_flow_keys pkt_v6_flow_keys = {
+ .nhoff = 0,
+ .thoff = sizeof(struct ipv6hdr),
+ .addr_proto = ETH_P_IPV6,
+ .ip_proto = IPPROTO_TCP,
+ .n_proto = bpf_htons(ETH_P_IPV6),
+};
+
+static void test_flow_dissector(void)
+{
+ struct bpf_flow_keys flow_keys;
+ struct bpf_object *obj;
+ __u32 duration, retval;
+ int err, prog_fd;
+ __u32 size;
+
+ err = bpf_flow_load(&obj, "./bpf_flow.o", "flow_dissector",
+ "jmp_table", &prog_fd);
+ if (err) {
+ error_cnt++;
+ return;
+ }
+
+ err = bpf_prog_test_run(prog_fd, 10, &pkt_v4, sizeof(pkt_v4),
+ &flow_keys, &size, &retval, &duration);
+ CHECK(size != sizeof(flow_keys) || err || retval != 1, "ipv4",
+ "err %d errno %d retval %d duration %d size %u/%lu\n",
+ err, errno, retval, duration, size, sizeof(flow_keys));
+ CHECK_FLOW_KEYS("ipv4_flow_keys", flow_keys, pkt_v4_flow_keys);
+
+ err = bpf_prog_test_run(prog_fd, 10, &pkt_v6, sizeof(pkt_v6),
+ &flow_keys, &size, &retval, &duration);
+ CHECK(size != sizeof(flow_keys) || err || retval != 1, "ipv6",
+ "err %d errno %d retval %d duration %d size %u/%lu\n",
+ err, errno, retval, duration, size, sizeof(flow_keys));
+ CHECK_FLOW_KEYS("ipv6_flow_keys", flow_keys, pkt_v6_flow_keys);
+
+ bpf_object__close(obj);
+}
+
int main(void)
{
srand(time(NULL));
@@ -1909,6 +1982,7 @@ int main(void)
test_reference_tracking();
test_queue_stack_map(QUEUE);
test_queue_stack_map(STACK);
+ test_flow_dissector();
printf("Summary: %d PASSED, %d FAILED\n", pass_cnt, error_cnt);
return error_cnt ? EXIT_FAILURE : EXIT_SUCCESS;
--
2.20.1.495.gaa96b0ce6b-goog
^ permalink raw reply related
* [PATCH bpf-next v3 2/3] bpf: add BPF_PROG_TEST_RUN support for flow dissector
From: Stanislav Fomichev @ 2019-01-28 16:53 UTC (permalink / raw)
To: netdev; +Cc: davem, ast, daniel, Stanislav Fomichev
In-Reply-To: <20190128165355.229403-1-sdf@google.com>
The input is packet data, the output is struct bpf_flow_key. This should
make it easy to test flow dissector programs without elaborate
setup.
Signed-off-by: Stanislav Fomichev <sdf@google.com>
---
include/linux/bpf.h | 3 ++
net/bpf/test_run.c | 82 +++++++++++++++++++++++++++++++++++++++++++++
net/core/filter.c | 1 +
3 files changed, 86 insertions(+)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 3851529062ec..0394f1f9213b 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -404,6 +404,9 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
union bpf_attr __user *uattr);
int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
union bpf_attr __user *uattr);
+int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog,
+ const union bpf_attr *kattr,
+ union bpf_attr __user *uattr);
/* an array of programs to be executed under rcu_lock.
*
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index fa2644d276ef..2c5172b33209 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -240,3 +240,85 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
kfree(data);
return ret;
}
+
+int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog,
+ const union bpf_attr *kattr,
+ union bpf_attr __user *uattr)
+{
+ u32 size = kattr->test.data_size_in;
+ u32 repeat = kattr->test.repeat;
+ struct bpf_flow_keys flow_keys;
+ u64 time_start, time_spent = 0;
+ struct bpf_skb_data_end *cb;
+ u32 retval, duration;
+ struct sk_buff *skb;
+ struct sock *sk;
+ void *data;
+ int ret;
+ u32 i;
+
+ if (prog->type != BPF_PROG_TYPE_FLOW_DISSECTOR)
+ return -EINVAL;
+
+ data = bpf_test_init(kattr, size, NET_SKB_PAD + NET_IP_ALIGN,
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+ sk = kzalloc(sizeof(*sk), GFP_USER);
+ if (!sk) {
+ kfree(data);
+ return -ENOMEM;
+ }
+ sock_net_set(sk, current->nsproxy->net_ns);
+ sock_init_data(NULL, sk);
+
+ skb = build_skb(data, 0);
+ if (!skb) {
+ kfree(data);
+ kfree(sk);
+ return -ENOMEM;
+ }
+ skb->sk = sk;
+
+ skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN);
+ __skb_put(skb, size);
+ skb->protocol = eth_type_trans(skb,
+ current->nsproxy->net_ns->loopback_dev);
+ skb_reset_network_header(skb);
+
+ cb = (struct bpf_skb_data_end *)skb->cb;
+ cb->qdisc_cb.flow_keys = &flow_keys;
+
+ if (!repeat)
+ repeat = 1;
+
+ time_start = ktime_get_ns();
+ for (i = 0; i < repeat; i++) {
+ preempt_disable();
+ rcu_read_lock();
+ retval = __skb_flow_bpf_dissect(prog, skb,
+ &flow_keys_dissector,
+ &flow_keys);
+ rcu_read_unlock();
+ preempt_enable();
+
+ if (need_resched()) {
+ if (signal_pending(current))
+ break;
+ time_spent += ktime_get_ns() - time_start;
+ cond_resched();
+ time_start = ktime_get_ns();
+ }
+ }
+ time_spent += ktime_get_ns() - time_start;
+ do_div(time_spent, repeat);
+ duration = time_spent > U32_MAX ? U32_MAX : (u32)time_spent;
+
+ ret = bpf_test_finish(kattr, uattr, &flow_keys, sizeof(flow_keys),
+ retval, duration);
+
+ kfree_skb(skb);
+ kfree(sk);
+ return ret;
+}
diff --git a/net/core/filter.c b/net/core/filter.c
index 8e587dd1da20..8ce421796ac6 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -7711,6 +7711,7 @@ const struct bpf_verifier_ops flow_dissector_verifier_ops = {
};
const struct bpf_prog_ops flow_dissector_prog_ops = {
+ .test_run = bpf_prog_test_run_flow_dissector,
};
int sk_detach_filter(struct sock *sk)
--
2.20.1.495.gaa96b0ce6b-goog
^ permalink raw reply related
* [PATCH bpf-next v3 1/3] net/flow_dissector: move bpf case into __skb_flow_bpf_dissect
From: Stanislav Fomichev @ 2019-01-28 16:53 UTC (permalink / raw)
To: netdev; +Cc: davem, ast, daniel, Stanislav Fomichev, Song Liu
In-Reply-To: <20190128165355.229403-1-sdf@google.com>
This way, we can reuse it for flow dissector in BPF_PROG_TEST_RUN.
No functional changes.
Signed-off-by: Stanislav Fomichev <sdf@google.com>
Acked-by: Song Liu <songliubraving@fb.com>
---
include/linux/skbuff.h | 5 +++
net/core/flow_dissector.c | 92 +++++++++++++++++++++++----------------
2 files changed, 59 insertions(+), 38 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 93f56fddd92a..be762fc34ff3 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1221,6 +1221,11 @@ static inline int skb_flow_dissector_bpf_prog_detach(const union bpf_attr *attr)
}
#endif
+struct bpf_flow_keys;
+bool __skb_flow_bpf_dissect(struct bpf_prog *prog,
+ const struct sk_buff *skb,
+ struct flow_dissector *flow_dissector,
+ struct bpf_flow_keys *flow_keys);
bool __skb_flow_dissect(const struct sk_buff *skb,
struct flow_dissector *flow_dissector,
void *target_container,
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 9f2840510e63..bb1a54747d64 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -683,6 +683,46 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys,
}
}
+bool __skb_flow_bpf_dissect(struct bpf_prog *prog,
+ const struct sk_buff *skb,
+ struct flow_dissector *flow_dissector,
+ struct bpf_flow_keys *flow_keys)
+{
+ struct bpf_skb_data_end cb_saved;
+ struct bpf_skb_data_end *cb;
+ u32 result;
+
+ /* Note that even though the const qualifier is discarded
+ * throughout the execution of the BPF program, all changes(the
+ * control block) are reverted after the BPF program returns.
+ * Therefore, __skb_flow_dissect does not alter the skb.
+ */
+
+ cb = (struct bpf_skb_data_end *)skb->cb;
+
+ /* Save Control Block */
+ memcpy(&cb_saved, cb, sizeof(cb_saved));
+ memset(cb, 0, sizeof(*cb));
+
+ /* Pass parameters to the BPF program */
+ memset(flow_keys, 0, sizeof(*flow_keys));
+ cb->qdisc_cb.flow_keys = flow_keys;
+ flow_keys->nhoff = skb_network_offset(skb);
+ flow_keys->thoff = flow_keys->nhoff;
+
+ bpf_compute_data_pointers((struct sk_buff *)skb);
+ result = BPF_PROG_RUN(prog, skb);
+
+ /* Restore state */
+ memcpy(cb, &cb_saved, sizeof(cb_saved));
+
+ flow_keys->nhoff = clamp_t(u16, flow_keys->nhoff, 0, skb->len);
+ flow_keys->thoff = clamp_t(u16, flow_keys->thoff,
+ flow_keys->nhoff, skb->len);
+
+ return result == BPF_OK;
+}
+
/**
* __skb_flow_dissect - extract the flow_keys struct and return it
* @skb: sk_buff to extract the flow from, can be NULL if the rest are specified
@@ -714,7 +754,6 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
struct flow_dissector_key_vlan *key_vlan;
enum flow_dissect_ret fdret;
enum flow_dissector_key_id dissector_vlan = FLOW_DISSECTOR_KEY_MAX;
- struct bpf_prog *attached = NULL;
int num_hdrs = 0;
u8 ip_proto = 0;
bool ret;
@@ -754,53 +793,30 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
FLOW_DISSECTOR_KEY_BASIC,
target_container);
- rcu_read_lock();
if (skb) {
+ struct bpf_flow_keys flow_keys;
+ struct bpf_prog *attached = NULL;
+
+ rcu_read_lock();
+
if (skb->dev)
attached = rcu_dereference(dev_net(skb->dev)->flow_dissector_prog);
else if (skb->sk)
attached = rcu_dereference(sock_net(skb->sk)->flow_dissector_prog);
else
WARN_ON_ONCE(1);
- }
- if (attached) {
- /* Note that even though the const qualifier is discarded
- * throughout the execution of the BPF program, all changes(the
- * control block) are reverted after the BPF program returns.
- * Therefore, __skb_flow_dissect does not alter the skb.
- */
- struct bpf_flow_keys flow_keys = {};
- struct bpf_skb_data_end cb_saved;
- struct bpf_skb_data_end *cb;
- u32 result;
-
- cb = (struct bpf_skb_data_end *)skb->cb;
-
- /* Save Control Block */
- memcpy(&cb_saved, cb, sizeof(cb_saved));
- memset(cb, 0, sizeof(cb_saved));
- /* Pass parameters to the BPF program */
- cb->qdisc_cb.flow_keys = &flow_keys;
- flow_keys.nhoff = nhoff;
- flow_keys.thoff = nhoff;
-
- bpf_compute_data_pointers((struct sk_buff *)skb);
- result = BPF_PROG_RUN(attached, skb);
-
- /* Restore state */
- memcpy(cb, &cb_saved, sizeof(cb_saved));
-
- flow_keys.nhoff = clamp_t(u16, flow_keys.nhoff, 0, skb->len);
- flow_keys.thoff = clamp_t(u16, flow_keys.thoff,
- flow_keys.nhoff, skb->len);
-
- __skb_flow_bpf_to_target(&flow_keys, flow_dissector,
- target_container);
+ if (attached) {
+ ret = __skb_flow_bpf_dissect(attached, skb,
+ flow_dissector,
+ &flow_keys);
+ __skb_flow_bpf_to_target(&flow_keys, flow_dissector,
+ target_container);
+ rcu_read_unlock();
+ return ret;
+ }
rcu_read_unlock();
- return result == BPF_OK;
}
- rcu_read_unlock();
if (dissector_uses_key(flow_dissector,
FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
--
2.20.1.495.gaa96b0ce6b-goog
^ permalink raw reply related
* [PATCH bpf-next v3 0/3] support flow dissector in BPF_PROG_TEST_RUN
From: Stanislav Fomichev @ 2019-01-28 16:53 UTC (permalink / raw)
To: netdev; +Cc: davem, ast, daniel, Stanislav Fomichev
This patch series adds support for testing flow dissector BPF programs by
extending already existing BPF_PROG_TEST_RUN. The goal is to have a
packet as an input and `struct bpf_flow_key' as an output. That way
we can easily test flow dissector programs' behavior.
I've also modified existing test_progs.c test to do a simple flow
dissector run as well.
* first patch introduces new __skb_flow_bpf_dissect to simplify
sharing between __skb_flow_bpf_dissect and BPF_PROG_TEST_RUN
* second patch adds actual BPF_PROG_TEST_RUN support
* third patch adds example usage to the selftests
v3:
* rebased on top of latest bpf-next
v2:
* loop over 'kattr->test.repeat' inside of
bpf_prog_test_run_flow_dissector, don't reuse
bpf_test_run/bpf_test_run_one
Stanislav Fomichev (3):
net/flow_dissector: move bpf case into __skb_flow_bpf_dissect
bpf: add BPF_PROG_TEST_RUN support for flow dissector
selftests/bpf: add simple BPF_PROG_TEST_RUN examples for flow
dissector
include/linux/bpf.h | 3 +
include/linux/skbuff.h | 5 +
net/bpf/test_run.c | 82 +++++++++++++++++
net/core/filter.c | 1 +
net/core/flow_dissector.c | 92 +++++++++++--------
tools/testing/selftests/bpf/Makefile | 3 +
.../selftests/bpf/flow_dissector_load.c | 43 +--------
.../selftests/bpf/flow_dissector_load.h | 55 +++++++++++
tools/testing/selftests/bpf/test_progs.c | 78 +++++++++++++++-
9 files changed, 284 insertions(+), 78 deletions(-)
create mode 100644 tools/testing/selftests/bpf/flow_dissector_load.h
--
2.20.1.495.gaa96b0ce6b-goog
^ permalink raw reply
* Re: [PATCH iproute2-next 1/2] tc: replace print_string with fprintf for error messages
From: David Ahern @ 2019-01-28 16:53 UTC (permalink / raw)
To: Stephen Hemminger, netdev
In-Reply-To: <20190124203014.7450-1-stephen@networkplumber.org>
On 1/24/19 1:30 PM, Stephen Hemminger wrote:
> diff --git a/tc/m_connmark.c b/tc/m_connmark.c
> index 45e2d05f1a91..34d80b1a27c0 100644
> --- a/tc/m_connmark.c
> +++ b/tc/m_connmark.c
> @@ -114,7 +114,7 @@ static int print_connmark(struct action_util *au, FILE *f, struct rtattr *arg)
>
> parse_rtattr_nested(tb, TCA_CONNMARK_MAX, arg);
> if (tb[TCA_CONNMARK_PARMS] == NULL) {
> - print_string(PRINT_FP, NULL, "%s", "[NULL connmark parameters]");
> + fprintf(stderr, "NULL connmark parameters\n");
> return -1;
> }
>
> diff --git a/tc/m_csum.c b/tc/m_csum.c
> index 752269d1d020..450f2b557b44 100644
> --- a/tc/m_csum.c
> +++ b/tc/m_csum.c
> @@ -172,7 +172,7 @@ print_csum(struct action_util *au, FILE *f, struct rtattr *arg)
> parse_rtattr_nested(tb, TCA_CSUM_MAX, arg);
>
> if (tb[TCA_CSUM_PARMS] == NULL) {
> - fprintf(f, "[NULL csum parameters]");
> + fprintf(stderr, "missing csum parameters\n");
> return -1;
> }
> sel = RTA_DATA(tb[TCA_CSUM_PARMS]);
> diff --git a/tc/m_gact.c b/tc/m_gact.c
> index a0a3c33d23da..342927bc2ed7 100644
> --- a/tc/m_gact.c
> +++ b/tc/m_gact.c
> @@ -174,7 +174,7 @@ print_gact(struct action_util *au, FILE *f, struct rtattr *arg)
> parse_rtattr_nested(tb, TCA_GACT_MAX, arg);
>
> if (tb[TCA_GACT_PARMS] == NULL) {
> - print_string(PRINT_FP, NULL, "%s", "[NULL gact parameters]");
> + fprintf(stderr, "[NULL gact parameters]\n");
We should be consistent and not showing the the '[]'. You have several
error messages with those included.
^ permalink raw reply
* Re: [PATCH net v4 2/2] net/mlx5e: Don't overwrite pedit action when multiple pedit used
From: Tonghao Zhang @ 2019-01-28 16:18 UTC (permalink / raw)
To: Or Gerlitz; +Cc: Saeed Mahameed, Linux Netdev List, Or Gerlitz
In-Reply-To: <CAJ3xEMijLMyUi3X6pfNN8NgMm+SLEV+fT9iGFkU1hr1WpkjY3w@mail.gmail.com>
On Mon, Jan 28, 2019 at 11:34 PM Or Gerlitz <gerlitz.or@gmail.com> wrote:
>
> On Mon, Jan 28, 2019 at 2:10 PM Tonghao Zhang <xiangxia.m.yue@gmail.com> wrote:
> > On Mon, Jan 28, 2019 at 12:40 AM Or Gerlitz <gerlitz.or@gmail.com> wrote:
> > >
> > > On Sun, Jan 27, 2019 at 1:06 PM <xiangxia.m.yue@gmail.com> wrote:
> > > > From: Tonghao Zhang <xiangxia.m.yue@gmail.com>
> > > >
> > > > In some case, we may use multiple pedit actions to modify packets.
> > > > The command shown as below: the last pedit action is effective.
> > >
> > > > @@ -2073,7 +2076,8 @@ static int alloc_mod_hdr_actions(struct mlx5e_priv *priv,
> > > > if (!parse_attr->mod_hdr_actions)
> > > > return -ENOMEM;
> > > >
> > > > - parse_attr->num_mod_hdr_actions = max_actions;
> > > > + parse_attr->max_mod_hdr_actions = max_actions;
> > > > + parse_attr->num_mod_hdr_actions = 0;
> > >
> > > why would we want to do this zeroing? what purpose does it serve?
> > Because we use the num_mod_hdr_actions to store the number of actions
> > we have parsed,
> > and when we alloc it, we init it 0 as default.
> >
> > > On a probably related note, I suspect that the patch broke the caching
> > > we do for modify header contexts, see mlx5e_attach_mod_hdr where we
> > > look if a given set of modify header operations already has hw modify header
> > > context and we use it.
> > >
> > > To test that, put two tc rules with different matching but same set of
> > > modify header
> > > (pedit) actions and see that only one modify header context is used.
>
> > The patch does't break the cache, I think that different matching may
> > share the same set of pedit actions.
>
> I suspect it does break it.. at [1] we have this code for the cache lookup:
>
> num_actions = parse_attr->num_mod_hdr_actions;
> [..]
> key.actions = parse_attr->mod_hdr_actions;
> key.num_actions = num_actions;
>
> hash_key = hash_mod_hdr_info(&key);
>
> so we are doing the cached insertion and lookup with
> parse_attr->num_mod_hdr_actions
> which was zeroed along the way and not accounting for the full set of
> pedit actions, agree?
not really, before calling the mlx5e_attach_mod_hdr, we have call
the offload_pedit_fields that will
update the attr->num_mod_hdr_actions that indicate how many pedit
action we parsed.
> [1] https://elixir.bootlin.com/linux/latest/source/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c#L179
^ permalink raw reply
* [PATCH AUTOSEL 4.14 156/170] isdn: hisax: hfc_pci: Fix a possible concurrency use-after-free bug in HFCPCI_l1hw()
From: Sasha Levin @ 2019-01-28 16:11 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Jia-Ju Bai, David S . Miller, Sasha Levin, netdev
In-Reply-To: <20190128161200.55107-1-sashal@kernel.org>
From: Jia-Ju Bai <baijiaju1990@gmail.com>
[ Upstream commit 7418e6520f22a2e35815122fa5a53d5bbfa2c10f ]
In drivers/isdn/hisax/hfc_pci.c, the functions hfcpci_interrupt() and
HFCPCI_l1hw() may be concurrently executed.
HFCPCI_l1hw()
line 1173: if (!cs->tx_skb)
hfcpci_interrupt()
line 942: spin_lock_irqsave();
line 1066: dev_kfree_skb_irq(cs->tx_skb);
Thus, a possible concurrency use-after-free bug may occur
in HFCPCI_l1hw().
To fix these bugs, the calls to spin_lock_irqsave() and
spin_unlock_irqrestore() are added in HFCPCI_l1hw(), to protect the
access to cs->tx_skb.
Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/isdn/hisax/hfc_pci.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
index f9ca35cc32b1..b42d27a4c950 100644
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -1169,11 +1169,13 @@ HFCPCI_l1hw(struct PStack *st, int pr, void *arg)
if (cs->debug & L1_DEB_LAPD)
debugl1(cs, "-> PH_REQUEST_PULL");
#endif
+ spin_lock_irqsave(&cs->lock, flags);
if (!cs->tx_skb) {
test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
} else
test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+ spin_unlock_irqrestore(&cs->lock, flags);
break;
case (HW_RESET | REQUEST):
spin_lock_irqsave(&cs->lock, flags);
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.14 158/170] fsl/fman: Use GFP_ATOMIC in {memac,tgec}_add_hash_mac_address()
From: Sasha Levin @ 2019-01-28 16:11 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Scott Wood, David S . Miller, Sasha Levin, netdev
In-Reply-To: <20190128161200.55107-1-sashal@kernel.org>
From: Scott Wood <oss@buserror.net>
[ Upstream commit 0d9c9a238faf925823bde866182c663b6d734f2e ]
These functions are called from atomic context:
[ 9.150239] BUG: sleeping function called from invalid context at /home/scott/git/linux/mm/slab.h:421
[ 9.158159] in_atomic(): 1, irqs_disabled(): 0, pid: 4432, name: ip
[ 9.163128] CPU: 8 PID: 4432 Comm: ip Not tainted 4.20.0-rc2-00169-g63d86876f324 #29
[ 9.163130] Call Trace:
[ 9.170701] [c0000002e899a980] [c0000000009c1068] .dump_stack+0xa8/0xec (unreliable)
[ 9.177140] [c0000002e899aa10] [c00000000007a7b4] .___might_sleep+0x138/0x164
[ 9.184440] [c0000002e899aa80] [c0000000001d5bac] .kmem_cache_alloc_trace+0x238/0x30c
[ 9.191216] [c0000002e899ab40] [c00000000065ea1c] .memac_add_hash_mac_address+0x104/0x198
[ 9.199464] [c0000002e899abd0] [c00000000065a788] .set_multi+0x1c8/0x218
[ 9.206242] [c0000002e899ac80] [c0000000006615ec] .dpaa_set_rx_mode+0xdc/0x17c
[ 9.213544] [c0000002e899ad00] [c00000000083d2b0] .__dev_set_rx_mode+0x80/0xd4
[ 9.219535] [c0000002e899ad90] [c00000000083d334] .dev_set_rx_mode+0x30/0x54
[ 9.225271] [c0000002e899ae10] [c00000000083d4a0] .__dev_open+0x148/0x1c8
[ 9.230751] [c0000002e899aeb0] [c00000000083d934] .__dev_change_flags+0x19c/0x1e0
[ 9.230755] [c0000002e899af60] [c00000000083d9a4] .dev_change_flags+0x2c/0x80
[ 9.242752] [c0000002e899aff0] [c0000000008554ec] .do_setlink+0x350/0xf08
[ 9.248228] [c0000002e899b170] [c000000000857ad0] .rtnl_newlink+0x588/0x7e0
[ 9.253965] [c0000002e899b740] [c000000000852424] .rtnetlink_rcv_msg+0x3e0/0x498
[ 9.261440] [c0000002e899b820] [c000000000884790] .netlink_rcv_skb+0x134/0x14c
[ 9.267607] [c0000002e899b8e0] [c000000000851840] .rtnetlink_rcv+0x18/0x2c
[ 9.274558] [c0000002e899b950] [c000000000883c8c] .netlink_unicast+0x214/0x318
[ 9.281163] [c0000002e899ba00] [c000000000884220] .netlink_sendmsg+0x348/0x444
[ 9.287076] [c0000002e899bae0] [c00000000080d13c] .sock_sendmsg+0x2c/0x54
[ 9.287080] [c0000002e899bb50] [c0000000008106c0] .___sys_sendmsg+0x2d0/0x2d8
[ 9.298375] [c0000002e899bd30] [c000000000811a80] .__sys_sendmsg+0x5c/0xb0
[ 9.303939] [c0000002e899be20] [c0000000000006b0] system_call+0x60/0x6c
Signed-off-by: Scott Wood <oss@buserror.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/freescale/fman/fman_memac.c | 2 +-
drivers/net/ethernet/freescale/fman/fman_tgec.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.c b/drivers/net/ethernet/freescale/fman/fman_memac.c
index c0296880feba..75ce773c21a6 100644
--- a/drivers/net/ethernet/freescale/fman/fman_memac.c
+++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
@@ -927,7 +927,7 @@ int memac_add_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr)
hash = get_mac_addr_hash_code(addr) & HASH_CTRL_ADDR_MASK;
/* Create element to be added to the driver hash table */
- hash_entry = kmalloc(sizeof(*hash_entry), GFP_KERNEL);
+ hash_entry = kmalloc(sizeof(*hash_entry), GFP_ATOMIC);
if (!hash_entry)
return -ENOMEM;
hash_entry->addr = addr;
diff --git a/drivers/net/ethernet/freescale/fman/fman_tgec.c b/drivers/net/ethernet/freescale/fman/fman_tgec.c
index 4b0f3a50b293..e575259d20f4 100644
--- a/drivers/net/ethernet/freescale/fman/fman_tgec.c
+++ b/drivers/net/ethernet/freescale/fman/fman_tgec.c
@@ -551,7 +551,7 @@ int tgec_add_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)
hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK;
/* Create element to be added to the driver hash table */
- hash_entry = kmalloc(sizeof(*hash_entry), GFP_KERNEL);
+ hash_entry = kmalloc(sizeof(*hash_entry), GFP_ATOMIC);
if (!hash_entry)
return -ENOMEM;
hash_entry->addr = addr;
--
2.19.1
^ permalink raw reply related
* Re: [PATCH iproute2-next 2/2] tc: replace left side comparison
From: David Ahern @ 2019-01-28 16:51 UTC (permalink / raw)
To: Stephen Hemminger, netdev
In-Reply-To: <20190124203014.7450-2-stephen@networkplumber.org>
On 1/24/19 1:30 PM, Stephen Hemminger wrote:
> The kernel (and iproute2) don't use the if (NULL == x) style
> and instead prefer if (!x)
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
> tc/m_action.c | 2 +-
> tc/m_ipt.c | 3 +--
> tc/m_xt_old.c | 3 +--
> tc/tc_util.c | 2 +-
> 4 files changed, 4 insertions(+), 6 deletions(-)
>
applied to iproute2-next. Thanks
^ permalink raw reply
* [PATCH AUTOSEL 4.9 005/107] ath9k: dynack: use authentication messages for 'late' ack
From: Sasha Levin @ 2019-01-28 16:18 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Lorenzo Bianconi, Kalle Valo, Sasha Levin, linux-wireless, netdev
In-Reply-To: <20190128161947.57405-1-sashal@kernel.org>
From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
[ Upstream commit 3831a2a0010c72e3956020cbf1057a1701a2e469 ]
In order to properly support dynack in ad-hoc mode running
wpa_supplicant, take into account authentication frames for
'late ack' detection. This patch has been tested on devices
mounted on offshore high-voltage stations connected through
~24Km link
Reported-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
Tested-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/ath/ath9k/dynack.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c
index 7334c9b09e82..cc0dc966c512 100644
--- a/drivers/net/wireless/ath/ath9k/dynack.c
+++ b/drivers/net/wireless/ath/ath9k/dynack.c
@@ -187,7 +187,8 @@ void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb,
/* late ACK */
if (ts->ts_status & ATH9K_TXERR_XRETRY) {
if (ieee80211_is_assoc_req(hdr->frame_control) ||
- ieee80211_is_assoc_resp(hdr->frame_control)) {
+ ieee80211_is_assoc_resp(hdr->frame_control) ||
+ ieee80211_is_auth(hdr->frame_control)) {
ath_dbg(common, DYNACK, "late ack\n");
ath9k_hw_setslottime(ah, (LATEACK_TO - 3) / 2);
ath9k_hw_set_ack_timeout(ah, LATEACK_TO);
--
2.19.1
^ permalink raw reply related
* RE: [PATCH net-next] net: hns3: Fix potential NULL dereference on allocation error
From: Salil Mehta @ 2019-01-28 16:47 UTC (permalink / raw)
To: yuehaibing, davem@davemloft.net, Zhuangyuzeng (Yisen), lipeng (Y)
Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org
In-Reply-To: <20190125031333.17196-1-yuehaibing@huawei.com>
> From: yuehaibing
> Sent: Friday, January 25, 2019 3:14 AM
> To: davem@davemloft.net; Zhuangyuzeng (Yisen) <yisen.zhuang@huawei.com>;
> Salil Mehta <salil.mehta@huawei.com>; lipeng (Y) <lipeng321@huawei.com>
> Cc: linux-kernel@vger.kernel.org; netdev@vger.kernel.org; yuehaibing <yuehaibing@huawei.com>
> Subject: [PATCH net-next] net: hns3: Fix potential NULL dereference on
> allocation error
>
> hclge_mac_update_stats_complete doesn't check for NULL
> returns of kcalloc, it may result in an Oops.
>
> Fixes: d174ea75c96a ("net: hns3: add statistics for PFC frames and MAC
> control frames")
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
> ---
> drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
> b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
> index 64b1589..7971606 100644
> --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
> +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
> @@ -343,6 +343,9 @@ static int hclge_mac_update_stats_complete(struct
> hclge_dev *hdev, u32 desc_num)
> int ret;
>
> desc = kcalloc(desc_num, sizeof(struct hclge_desc), GFP_KERNEL);
> + if (!desc)
> + return -ENOMEM;
> +
looks good to me.
Reviewed-by: Salil Mehta <salil.mehta@huawei.com>
^ permalink raw reply
* Re: [PATCH RFC 0/3] Support fraglist GRO/GSO
From: Willem de Bruijn @ 2019-01-28 16:46 UTC (permalink / raw)
To: Steffen Klassert
Cc: Network Development, Willem de Bruijn, Paolo Abeni,
Jason A. Donenfeld
In-Reply-To: <20190128075154.GE3581@gauss3.secunet.de>
On Mon, Jan 28, 2019 at 2:51 AM Steffen Klassert
<steffen.klassert@secunet.com> wrote:
>
> On Fri, Jan 25, 2019 at 08:57:00AM -0500, Willem de Bruijn wrote:
> > On Fri, Jan 25, 2019 at 3:14 AM Steffen Klassert
> > <steffen.klassert@secunet.com> wrote:
> > >
> > > On Mon, Jan 14, 2019 at 12:09:22PM -0500, Willem de Bruijn wrote:
> > > > On Mon, Jan 14, 2019 at 7:50 AM Steffen Klassert
> > > > <steffen.klassert@secunet.com> wrote:
> > > > > On Sun, Dec 23, 2018 at 08:15:40PM -0500, Willem de Bruijn wrote:
> > > >
> > > > I don't think that the route lookup is needed. If listified is cheaper
> > > > for local delivery, too, then we can make that the default unless a
> > > > device is active with h/w offload and ip forwarding is enabled. If it
> > > > isn't, then use it iff ip forwarding is enabled. I think it's fine to
> > > > mispredict between the two in edge cases with netfilter mangling, as
> > > > long as all paths can correctly handle both types of GRO packets.
> > >
> > > I'd need at least a route lookup for my usecase, because listified
> > > GRO is always cheaper when a xfrm transformation is needed (even for
> > > TCP). In this case is software GSO needed. So I'd need to either have
> > > an early route lookup or maybe some early ingress hook where a route
> > > lookup could be imlemented in.
> >
> > Could you use a similar system wide approach as what we discussed
> > previous wrt hardware offload? Use listified only if (forwarding is enabled
> > and no device is registered that implements h/w segmentation offload) or
> > any path requires xfrm transformation (?).
>
> The xfrm transformation has to happen for the segments. So if we need to
> do xfrm transformation in software, we need to do segmentation in
> software too. I think that just forwarding is enabled and the presence
> of a device that can do hardware segmentation offload is not a good
> indicator. The more devices support hardware segmentation offload
> the more likely is it that xfrm take a suboptimal path.
That's why I suggested OR any path requires xfrm.
> We have to do a route lookup anyway, why not just do it early
> in case forwarding is enabled?
But actually, yes, that's true, so fine, too.
^ permalink raw reply
* [PATCH AUTOSEL 4.9 067/107] Bluetooth: Fix unnecessary error message for HCI request completion
From: Sasha Levin @ 2019-01-28 16:19 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Johan Hedberg, Marcel Holtmann, Sasha Levin, linux-bluetooth,
netdev
In-Reply-To: <20190128161947.57405-1-sashal@kernel.org>
From: Johan Hedberg <johan.hedberg@intel.com>
[ Upstream commit 1629db9c75342325868243d6bca5853017d91cf8 ]
In case a command which completes in Command Status was sent using the
hci_cmd_send-family of APIs there would be a misleading error in the
hci_get_cmd_complete function, since the code would be trying to fetch
the Command Complete parameters when there are none.
Avoid the misleading error and silently bail out from the function in
case the received event is a command status.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/hci_event.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index d2f9eb169ba8..6f78489fdb13 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -5212,6 +5212,12 @@ static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
return true;
}
+ /* Check if request ended in Command Status - no way to retreive
+ * any extra parameters in this case.
+ */
+ if (hdr->evt == HCI_EV_CMD_STATUS)
+ return false;
+
if (hdr->evt != HCI_EV_CMD_COMPLETE) {
BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
return false;
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.9 065/107] mac80211: fix radiotap vendor presence bitmap handling
From: Sasha Levin @ 2019-01-28 16:19 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Johannes Berg, Luca Coelho, Sasha Levin, linux-wireless, netdev
In-Reply-To: <20190128161947.57405-1-sashal@kernel.org>
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit efc38dd7d5fa5c8cdd0c917c5d00947aa0539443 ]
Due to the alignment handling, it actually matters where in the code
we add the 4 bytes for the presence bitmap to the length; the first
field is the timestamp with 8 byte alignment so we need to add the
space for the extra vendor namespace presence bitmap *before* we do
any alignment for the fields.
Move the presence bitmap length accounting to the right place to fix
the alignment for the data properly.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/rx.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 93c332737e86..af02d2136a06 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -152,6 +152,9 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local,
/* allocate extra bitmaps */
if (status->chains)
len += 4 * hweight8(status->chains);
+ /* vendor presence bitmap */
+ if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA)
+ len += 4;
if (ieee80211_have_rx_timestamp(status)) {
len = ALIGN(len, 8);
@@ -193,8 +196,6 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local,
if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA) {
struct ieee80211_vendor_radiotap *rtap = (void *)skb->data;
- /* vendor presence bitmap */
- len += 4;
/* alignment for fixed 6-byte vendor data header */
len = ALIGN(len, 2);
/* vendor data header */
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.9 070/107] cw1200: Fix concurrency use-after-free bugs in cw1200_hw_scan()
From: Sasha Levin @ 2019-01-28 16:19 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Jia-Ju Bai, Kalle Valo, Sasha Levin, linux-wireless, netdev
In-Reply-To: <20190128161947.57405-1-sashal@kernel.org>
From: Jia-Ju Bai <baijiaju1990@gmail.com>
[ Upstream commit 4f68ef64cd7feb1220232bd8f501d8aad340a099 ]
The function cw1200_bss_info_changed() and cw1200_hw_scan() can be
concurrently executed.
The two functions both access a possible shared variable "frame.skb".
This shared variable is freed by dev_kfree_skb() in cw1200_upload_beacon(),
which is called by cw1200_bss_info_changed(). The free operation is
protected by a mutex lock "priv->conf_mutex" in cw1200_bss_info_changed().
In cw1200_hw_scan(), this shared variable is accessed without the
protection of the mutex lock "priv->conf_mutex".
Thus, concurrency use-after-free bugs may occur.
To fix these bugs, the original calls to mutex_lock(&priv->conf_mutex) and
mutex_unlock(&priv->conf_mutex) are moved to the places, which can
protect the accesses to the shared variable.
Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/st/cw1200/scan.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/st/cw1200/scan.c b/drivers/net/wireless/st/cw1200/scan.c
index 0a0ff7e31f5b..c5492d792f43 100644
--- a/drivers/net/wireless/st/cw1200/scan.c
+++ b/drivers/net/wireless/st/cw1200/scan.c
@@ -78,6 +78,10 @@ int cw1200_hw_scan(struct ieee80211_hw *hw,
if (req->n_ssids > WSM_SCAN_MAX_NUM_OF_SSIDS)
return -EINVAL;
+ /* will be unlocked in cw1200_scan_work() */
+ down(&priv->scan.lock);
+ mutex_lock(&priv->conf_mutex);
+
frame.skb = ieee80211_probereq_get(hw, priv->vif->addr, NULL, 0,
req->ie_len);
if (!frame.skb)
@@ -86,19 +90,15 @@ int cw1200_hw_scan(struct ieee80211_hw *hw,
if (req->ie_len)
memcpy(skb_put(frame.skb, req->ie_len), req->ie, req->ie_len);
- /* will be unlocked in cw1200_scan_work() */
- down(&priv->scan.lock);
- mutex_lock(&priv->conf_mutex);
-
ret = wsm_set_template_frame(priv, &frame);
if (!ret) {
/* Host want to be the probe responder. */
ret = wsm_set_probe_responder(priv, true);
}
if (ret) {
+ dev_kfree_skb(frame.skb);
mutex_unlock(&priv->conf_mutex);
up(&priv->scan.lock);
- dev_kfree_skb(frame.skb);
return ret;
}
@@ -120,10 +120,9 @@ int cw1200_hw_scan(struct ieee80211_hw *hw,
++priv->scan.n_ssids;
}
- mutex_unlock(&priv->conf_mutex);
-
if (frame.skb)
dev_kfree_skb(frame.skb);
+ mutex_unlock(&priv->conf_mutex);
queue_work(priv->workqueue, &priv->scan.work);
return 0;
}
--
2.19.1
^ permalink raw reply related
* Re: [PATCH bpf-next v2 0/3] selftests: bpf: break up test_verifier
From: Jakub Kicinski @ 2019-01-28 16:45 UTC (permalink / raw)
To: Alexei Starovoitov; +Cc: Daniel Borkmann, netdev
In-Reply-To: <20190128055719.kqvebv2ievpklydy@ast-mbp>
On Sun, 27 Jan 2019 21:57:20 -0800, Alexei Starovoitov wrote:
> My tripple check failed.
> Turned out that the eariler attempt to merge it created
> selftests/bpf/verifier/ directory with .gitignore file inside it
> and 'git am --abort' and 'git rebase --hard' kept it in place.
> (since .gitignore was there)
>
> 'git' wasn't very helpful with the following message either:
> ----
> Applying: selftests: bpf: prepare for break up of verifier tests
> error: sha1 information is lacking or useless (tools/testing/selftests/bpf/Makefile).
> error: could not build fake ancestor
> Patch failed at 0001 selftests: bpf: prepare for break up of verifier tests
Aw, weirdness.
> But the odds were in my favor tonight :)
>
> Applied to bpf-next. Thanks!
Awesome :)
^ permalink raw reply
* [PATCH AUTOSEL 4.9 078/107] igb: Fix an issue that PME is not enabled during runtime suspend
From: Sasha Levin @ 2019-01-28 16:19 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Kai-Heng Feng, Jeff Kirsher, Sasha Levin, netdev
In-Reply-To: <20190128161947.57405-1-sashal@kernel.org>
From: Kai-Heng Feng <kai.heng.feng@canonical.com>
[ Upstream commit 1fb3a7a75e2efcc83ef21f2434069cddd6fae6f5 ]
I210 ethernet card doesn't wakeup when a cable gets plugged. It's
because its PME is not set.
Since commit 42eca2302146 ("PCI: Don't touch card regs after runtime
suspend D3"), if the PCI state is saved, pci_pm_runtime_suspend() stops
calling pci_finish_runtime_suspend(), which enables the PCI PME.
To fix the issue, let's not to save PCI states when it's runtime
suspend, to let the PCI subsystem enables PME.
Fixes: 42eca2302146 ("PCI: Don't touch card regs after runtime suspend D3")
Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/intel/igb/igb_main.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 3a61491421b1..82e48e355fb9 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -7564,9 +7564,11 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake,
rtnl_unlock();
#ifdef CONFIG_PM
- retval = pci_save_state(pdev);
- if (retval)
- return retval;
+ if (!runtime) {
+ retval = pci_save_state(pdev);
+ if (retval)
+ return retval;
+ }
#endif
status = rd32(E1000_STATUS);
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.9 077/107] i40e: define proper net_device::neigh_priv_len
From: Sasha Levin @ 2019-01-28 16:19 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Konstantin Khorenko, Jeff Kirsher, Sasha Levin, netdev
In-Reply-To: <20190128161947.57405-1-sashal@kernel.org>
From: Konstantin Khorenko <khorenko@virtuozzo.com>
[ Upstream commit 31389b53b3e0b535867af9090a5d19ec64768d55 ]
Out of bound read reported by KASan.
i40iw_net_event() reads unconditionally 16 bytes from
neigh->primary_key while the memory allocated for
"neighbour" struct is evaluated in neigh_alloc() as
tbl->entry_size + dev->neigh_priv_len
where "dev" is a net_device.
But the driver does not setup dev->neigh_priv_len and
we read beyond the neigh entry allocated memory,
so the patch in the next mail fixes this.
Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 57c7456a5751..7836072d3f63 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -9194,6 +9194,9 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
ether_addr_copy(netdev->dev_addr, mac_addr);
ether_addr_copy(netdev->perm_addr, mac_addr);
+ /* i40iw_net_event() reads 16 bytes from neigh->primary_key */
+ netdev->neigh_priv_len = sizeof(u32) * 4;
+
netdev->priv_flags |= IFF_UNICAST_FLT;
netdev->priv_flags |= IFF_SUPP_NOFCS;
/* Setup netdev TC information */
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.9 092/107] niu: fix missing checks of niu_pci_eeprom_read
From: Sasha Levin @ 2019-01-28 16:19 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Kangjie Lu, David S . Miller, Sasha Levin, netdev
In-Reply-To: <20190128161947.57405-1-sashal@kernel.org>
From: Kangjie Lu <kjlu@umn.edu>
[ Upstream commit 26fd962bde0b15e54234fe762d86bc0349df1de4 ]
niu_pci_eeprom_read() may fail, so we should check its return value
before using the read data.
Signed-off-by: Kangjie Lu <kjlu@umn.edu>
Acked-by: Shannon Nelson <shannon.lee.nelson@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/sun/niu.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
index e45e2f14fb94..fe5b0ac8c631 100644
--- a/drivers/net/ethernet/sun/niu.c
+++ b/drivers/net/ethernet/sun/niu.c
@@ -8121,6 +8121,8 @@ static int niu_pci_vpd_scan_props(struct niu *np, u32 start, u32 end)
start += 3;
prop_len = niu_pci_eeprom_read(np, start + 4);
+ if (prop_len < 0)
+ return prop_len;
err = niu_pci_vpd_get_propname(np, start + 5, namebuf, 64);
if (err < 0)
return err;
@@ -8165,8 +8167,12 @@ static int niu_pci_vpd_scan_props(struct niu *np, u32 start, u32 end)
netif_printk(np, probe, KERN_DEBUG, np->dev,
"VPD_SCAN: Reading in property [%s] len[%d]\n",
namebuf, prop_len);
- for (i = 0; i < prop_len; i++)
- *prop_buf++ = niu_pci_eeprom_read(np, off + i);
+ for (i = 0; i < prop_len; i++) {
+ err = niu_pci_eeprom_read(np, off + i);
+ if (err >= 0)
+ *prop_buf = err;
+ ++prop_buf;
+ }
}
start += len;
--
2.19.1
^ permalink raw reply related
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