* Re: [PATCH net-next v5 1/4] bpf: add helper bpf_perf_event_read_value for perf event array map
From: Yonghong Song @ 2017-09-25 15:41 UTC (permalink / raw)
To: Alexei Starovoitov, David Miller, peterz
Cc: rostedt, daniel, netdev, kernel-team
In-Reply-To: <b9753171-8e70-92f2-9852-8d3a33f2c07c@fb.com>
On 9/21/17 8:15 AM, Alexei Starovoitov wrote:
> On 9/20/17 4:07 PM, David Miller wrote:
>> From: Peter Zijlstra <peterz@infradead.org>
>> Date: Wed, 20 Sep 2017 19:26:51 +0200
>>
>>> Dave, could we have this in a topic tree of sorts, because I have a
>>> pending series to rework all the timekeeping and it might be nice to not
>>> have sfr run into all sorts of conflicts.
>>
>> If you want to merge it into your tree that's fine.
>>
>> But it means that any further development done on top of this
>> work will need to go via you as well.
>
> can we merge this set of patches into both net-next and tip ?
> We did such tricks in the past to avoid merge conflicts and
> everything went fine during merge window.
Hi, Peter,
Any suggestion for merging this patch? Alexei's idea sounds
reasonable?
Thanks,
Yonghong
^ permalink raw reply
* [PATCH net] inetpeer: fix RCU lookup() again
From: Eric Dumazet @ 2017-09-25 15:40 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
My prior fix was not complete, as we were dereferencing a pointer
three times per node, not twice as I initially thought.
Fixes: 4cc5b44b29a9 ("inetpeer: fix RCU lookup()")
Fixes: b145425f269a ("inetpeer: remove AVL implementation in favor of RB tree")
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/ipv4/inetpeer.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index e7eb590c86ce2b33654c17c61619de74ff07bfd1..b20c8ac640811e1b4c5416134181dd77675db878 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -128,9 +128,9 @@ static struct inet_peer *lookup(const struct inetpeer_addr *daddr,
break;
}
if (cmp == -1)
- pp = &(*pp)->rb_left;
+ pp = &next->rb_left;
else
- pp = &(*pp)->rb_right;
+ pp = &next->rb_right;
}
*parent_p = parent;
*pp_p = pp;
^ permalink raw reply related
* Re: [PATCH net-next 0/7] nfp: flower vxlan tunnel offload
From: Or Gerlitz @ 2017-09-25 15:25 UTC (permalink / raw)
To: Simon Horman; +Cc: David Miller, Jakub Kicinski, Linux Netdev List, oss-drivers
In-Reply-To: <1506335021-32024-1-git-send-email-simon.horman@netronome.com>
On Mon, Sep 25, 2017 at 1:23 PM, Simon Horman
<simon.horman@netronome.com> wrote:
> From: Simon Horman <simon.horman@netronome.com>
>
> John says:
>
> This patch set allows offloading of TC flower match and set tunnel fields
> to the NFP. The initial focus is on VXLAN traffic. Due to the current
> state of the NFP firmware, only VXLAN traffic on well known port 4789 is
> handled. The match and action fields must explicity set this value to be
> supported. Tunnel end point information is also offloaded to the NFP for
> both encapsulation and decapsulation. The NFP expects 3 separate data sets
> to be supplied.
> For decapsulation, 2 separate lists exist; a list of MAC addresses
> referenced by an index comprised of the port number, and a list of IP
> addresses. These IP addresses are not connected to a MAC or port.
Do these IP addresses exist on the host kernel SW stack? can the same
set of TC rules be fully functional and generate the same traffic
pattern when set to run in SW (skip_hw)?
> The MAC
> addresses can be written as a block or one at a time (because they have an
> index, previous values can be overwritten) while the IP addresses are
> always written as a list of all the available IPs. Because the MAC address
> used as a tunnel end point may be associated with a physical port or may
> be a virtual netdev like an OVS bridge, we do not know which addresses
> should be offloaded. For this reason, all MAC addresses of active netdevs
> are offloaded to the NFP. A notifier checks for changes to any currently
> offloaded MACs or any new netdevs that may occur. For IP addresses, the
> tunnel end point used in the rules is known as the destination IP address
> must be specified in the flower classifier rule. When a new IP address
> appears in a rule, the IP address is offloaded. The IP is removed from the
> offloaded list when all rules matching on that IP are deleted.
>
> For encapsulation, a next hop table is updated on the NFP that contains
> the source/dest IPs, MACs and egress port. These are written individually
> when requested. If the NFP tries to encapsulate a packet but does not know
> the next hop, then is sends a request to the host. The host carries out a
> route lookup and populates the given entry on the NFP table. A notifier
> also exists to check for any links changing or going down in the kernel
> next hop table. If an offloaded next hop entry is removed from the kernel
> then it is also removed on the NFP.
>
> The NFP periodically sends a message to the host telling it which tunnel
> ports have packets egressing the system. The host uses this information to
> update the used value in the neighbour entry. This means that, rather than
> expire when it times out, the kernel will send an ARP to check if the link
> is still live. From an NFP perspective, this means that valid entries will
> not be removed from its next hop table.
>
> John Hurley (7):
> nfp: add helper to get flower cmsg length
> nfp: compile flower vxlan tunnel metadata match fields
> nfp: compile flower vxlan tunnel set actions
> nfp: offload flower vxlan endpoint MAC addresses
> nfp: offload vxlan IPv4 endpoints of flower rules
> nfp: flower vxlan neighbour offload
> nfp: flower vxlan neighbour keep-alive
>
> drivers/net/ethernet/netronome/nfp/Makefile | 3 +-
> drivers/net/ethernet/netronome/nfp/flower/action.c | 169 ++++-
> drivers/net/ethernet/netronome/nfp/flower/cmsg.c | 16 +-
> drivers/net/ethernet/netronome/nfp/flower/cmsg.h | 87 ++-
> drivers/net/ethernet/netronome/nfp/flower/main.c | 13 +
> drivers/net/ethernet/netronome/nfp/flower/main.h | 35 +
> drivers/net/ethernet/netronome/nfp/flower/match.c | 75 +-
> .../net/ethernet/netronome/nfp/flower/metadata.c | 2 +-
> .../net/ethernet/netronome/nfp/flower/offload.c | 74 +-
> .../ethernet/netronome/nfp/flower/tunnel_conf.c | 811 +++++++++++++++++++++
> 10 files changed, 1243 insertions(+), 42 deletions(-)
> create mode 100644 drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
>
> --
> 2.1.4
>
^ permalink raw reply
* Re: [PATCH net v2] sctp: Fix a big endian bug in sctp_diag_dump()
From: Xin Long @ 2017-09-25 15:00 UTC (permalink / raw)
To: Dan Carpenter
Cc: Vlad Yasevich, Neil Horman, David S. Miller, linux-sctp,
network dev, kernel-janitors
In-Reply-To: <20170925101926.db4f6x4hblh7tcvo@mwanda>
On Mon, Sep 25, 2017 at 6:19 PM, Dan Carpenter <dan.carpenter@oracle.com> wrote:
> The sctp_for_each_transport() function takes an pointer to int. The
> cb->args[] array holds longs so it's only using the high 32 bits. It
> works on little endian system but will break on big endian 64 bit
> machines.
>
> Fixes: d25adbeb0cdb ("sctp: fix an use-after-free issue in sctp_sock_dump")
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> ---
> v2: The v1 patch changed the function to take a long pointer, but v2
> just changes the caller.
>
> diff --git a/net/sctp/sctp_diag.c b/net/sctp/sctp_diag.c
> index 22ed01a76b19..a72a7d925d46 100644
> --- a/net/sctp/sctp_diag.c
> +++ b/net/sctp/sctp_diag.c
> @@ -463,6 +463,7 @@ static void sctp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
> .r = r,
> .net_admin = netlink_net_capable(cb->skb, CAP_NET_ADMIN),
> };
> + int pos = cb->args[2];
>
> /* eps hashtable dumps
> * args:
> @@ -493,7 +494,8 @@ static void sctp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
> goto done;
>
> sctp_for_each_transport(sctp_sock_filter, sctp_sock_dump,
> - net, (int *)&cb->args[2], &commp);
> + net, &pos, &commp);
> + cb->args[2] = pos;
>
> done:
> cb->args[1] = cb->args[4];
Reviewed-by: Xin Long <lucien.xin@gmail.com>
^ permalink raw reply
* Re: [PATCH] r8152: add Linksys USB3GIGV1 id
From: Oliver Neukum @ 2017-09-25 14:51 UTC (permalink / raw)
To: Grant Grundler, Hayes Wang; +Cc: David S . Miller, LKML, linux-usb, netdev
In-Reply-To: <20170922190604.108155-1-grundler@chromium.org>
Am Freitag, den 22.09.2017, 12:06 -0700 schrieb Grant Grundler:
> This Linksys dongle by default comes up in cdc_ether mode.
> This patch allows r8152 to claim the device:
> Bus 002 Device 002: ID 13b1:0041 Linksys
Hi,
have you tested this in case cdc_ether is for some reason already
loaded? The patch seems to enable r8152 but does not disable
cdc_ether.
Regards
Oliver
^ permalink raw reply
* RE: [PATCH v4 4/9] em28xx: fix em28xx_dvb_init for KASAN
From: David Laight @ 2017-09-25 14:41 UTC (permalink / raw)
To: 'Arnd Bergmann', Mauro Carvalho Chehab
Cc: Jiri Pirko, Arend van Spriel, Kalle Valo, David S. Miller,
Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
Masahiro Yamada, Michal Marek, Andrew Morton, Kees Cook,
Geert Uytterhoeven, Greg Kroah-Hartman,
linux-media@vger.kernel.org, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org, linux-wireless@vger.kernel.org
In-Reply-To: <20170922212930.620249-5-arnd@arndb.de>
From: Arnd Bergmann
> Sent: 22 September 2017 22:29
...
> It seems that this is triggered in part by using strlcpy(), which the
> compiler doesn't recognize as copying at most 'len' bytes, since strlcpy
> is not part of the C standard.
Neither is strncpy().
It'll almost certainly be a marker in a header file somewhere,
so it should be possibly to teach it about other functions.
David
^ permalink raw reply
* [PATCH net-next v9] openvswitch: enable NSH support
From: Yi Yang @ 2017-09-25 14:16 UTC (permalink / raw)
To: netdev; +Cc: dev, jbenc, e, davem, Yi Yang
v8->v9
- Fix build error reported by daily intel build
because nsh module isn't selected by openvswitch
v7->v8
- Rework nested value and mask for OVS_KEY_ATTR_NSH
- Change pop_nsh to adapt to nsh kernel module
- Fix many issues per comments from Jiri Benc
v6->v7
- Remove NSH GSO patches in v6 because Jiri Benc
reworked it as another patch series and they have
been merged.
- Change it to adapt to nsh kernel module added by NSH
GSO patch series
v5->v6
- Fix the rest comments for v4.
- Add NSH GSO support for VxLAN-gpe + NSH and
Eth + NSH.
v4->v5
- Fix many comments by Jiri Benc and Eric Garver
for v4.
v3->v4
- Add new NSH match field ttl
- Update NSH header to the latest format
which will be final format and won't change
per its author's confirmation.
- Fix comments for v3.
v2->v3
- Change OVS_KEY_ATTR_NSH to nested key to handle
length-fixed attributes and length-variable
attriubte more flexibly.
- Remove struct ovs_action_push_nsh completely
- Add code to handle nested attribute for SET_MASKED
- Change PUSH_NSH to use the nested OVS_KEY_ATTR_NSH
to transfer NSH header data.
- Fix comments and coding style issues by Jiri and Eric
v1->v2
- Change encap_nsh and decap_nsh to push_nsh and pop_nsh
- Dynamically allocate struct ovs_action_push_nsh for
length-variable metadata.
OVS master and 2.8 branch has merged NSH userspace
patch series, this patch is to enable NSH support
in kernel data path in order that OVS can support
NSH in compat mode by porting this.
Signed-off-by: Yi Yang <yi.y.yang@intel.com>
---
include/net/nsh.h | 3 +
include/uapi/linux/openvswitch.h | 29 ++++
net/nsh/nsh.c | 53 +++++++
net/openvswitch/Kconfig | 1 +
net/openvswitch/actions.c | 112 ++++++++++++++
net/openvswitch/flow.c | 51 ++++++
net/openvswitch/flow.h | 11 ++
net/openvswitch/flow_netlink.c | 324 ++++++++++++++++++++++++++++++++++++++-
net/openvswitch/flow_netlink.h | 5 +
9 files changed, 588 insertions(+), 1 deletion(-)
diff --git a/include/net/nsh.h b/include/net/nsh.h
index a1eaea2..b886d33 100644
--- a/include/net/nsh.h
+++ b/include/net/nsh.h
@@ -304,4 +304,7 @@ static inline void nsh_set_flags_ttl_len(struct nshhdr *nsh, u8 flags,
NSH_FLAGS_MASK | NSH_TTL_MASK | NSH_LEN_MASK);
}
+int skb_push_nsh(struct sk_buff *skb, const struct nshhdr *src_nsh_hdr);
+int skb_pop_nsh(struct sk_buff *skb);
+
#endif /* __NET_NSH_H */
diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h
index 156ee4c..c1a785c 100644
--- a/include/uapi/linux/openvswitch.h
+++ b/include/uapi/linux/openvswitch.h
@@ -333,6 +333,7 @@ enum ovs_key_attr {
OVS_KEY_ATTR_CT_LABELS, /* 16-octet connection tracking label */
OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4, /* struct ovs_key_ct_tuple_ipv4 */
OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6, /* struct ovs_key_ct_tuple_ipv6 */
+ OVS_KEY_ATTR_NSH, /* Nested set of ovs_nsh_key_* */
#ifdef __KERNEL__
OVS_KEY_ATTR_TUNNEL_INFO, /* struct ip_tunnel_info */
@@ -491,6 +492,30 @@ struct ovs_key_ct_tuple_ipv6 {
__u8 ipv6_proto;
};
+enum ovs_nsh_key_attr {
+ OVS_NSH_KEY_ATTR_UNSPEC,
+ OVS_NSH_KEY_ATTR_BASE, /* struct ovs_nsh_key_base. */
+ OVS_NSH_KEY_ATTR_MD1, /* struct ovs_nsh_key_md1. */
+ OVS_NSH_KEY_ATTR_MD2, /* variable-length octets for MD type 2. */
+ __OVS_NSH_KEY_ATTR_MAX
+};
+
+#define OVS_NSH_KEY_ATTR_MAX (__OVS_NSH_KEY_ATTR_MAX - 1)
+
+struct ovs_nsh_key_base {
+ __u8 flags;
+ __u8 ttl;
+ __u8 mdtype;
+ __u8 np;
+ __be32 path_hdr;
+};
+
+#define NSH_MD1_CONTEXT_SIZE 4
+
+struct ovs_nsh_key_md1 {
+ __be32 context[NSH_MD1_CONTEXT_SIZE];
+};
+
/**
* enum ovs_flow_attr - attributes for %OVS_FLOW_* commands.
* @OVS_FLOW_ATTR_KEY: Nested %OVS_KEY_ATTR_* attributes specifying the flow
@@ -806,6 +831,8 @@ struct ovs_action_push_eth {
* packet.
* @OVS_ACTION_ATTR_POP_ETH: Pop the outermost Ethernet header off the
* packet.
+ * @OVS_ACTION_ATTR_PUSH_NSH: push NSH header to the packet.
+ * @OVS_ACTION_ATTR_POP_NSH: pop the outermost NSH header off the packet.
*
* Only a single header can be set with a single %OVS_ACTION_ATTR_SET. Not all
* fields within a header are modifiable, e.g. the IPv4 protocol and fragment
@@ -835,6 +862,8 @@ enum ovs_action_attr {
OVS_ACTION_ATTR_TRUNC, /* u32 struct ovs_action_trunc. */
OVS_ACTION_ATTR_PUSH_ETH, /* struct ovs_action_push_eth. */
OVS_ACTION_ATTR_POP_ETH, /* No argument. */
+ OVS_ACTION_ATTR_PUSH_NSH, /* Nested OVS_NSH_KEY_ATTR_*. */
+ OVS_ACTION_ATTR_POP_NSH, /* No argument. */
__OVS_ACTION_ATTR_MAX, /* Nothing past this will be accepted
* from userspace. */
diff --git a/net/nsh/nsh.c b/net/nsh/nsh.c
index 58fb827..54334ca 100644
--- a/net/nsh/nsh.c
+++ b/net/nsh/nsh.c
@@ -14,6 +14,59 @@
#include <net/nsh.h>
#include <net/tun_proto.h>
+int skb_push_nsh(struct sk_buff *skb, const struct nshhdr *src_nsh_hdr)
+{
+ struct nshhdr *nsh_hdr;
+ size_t length = nsh_hdr_len(src_nsh_hdr);
+ u8 next_proto;
+
+ if (skb->mac_len) {
+ next_proto = TUN_P_ETHERNET;
+ } else {
+ next_proto = tun_p_from_eth_p(skb->protocol);
+ if (!next_proto)
+ return -EAFNOSUPPORT;
+ }
+
+ /* Add the NSH header */
+ if (skb_cow_head(skb, length) < 0)
+ return -ENOMEM;
+
+ skb_push(skb, length);
+ nsh_hdr = (struct nshhdr *)(skb->data);
+ memcpy(nsh_hdr, src_nsh_hdr, length);
+ nsh_hdr->np = next_proto;
+
+ skb->protocol = htons(ETH_P_NSH);
+ skb_reset_mac_header(skb);
+ skb_reset_mac_len(skb);
+ skb_reset_network_header(skb);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(skb_push_nsh);
+
+int skb_pop_nsh(struct sk_buff *skb)
+{
+ struct nshhdr *nsh_hdr = (struct nshhdr *)(skb->data);
+ size_t length;
+ u16 inner_proto;
+
+ inner_proto = tun_p_to_eth_p(nsh_hdr->np);
+ if (!inner_proto)
+ return -EAFNOSUPPORT;
+
+ length = nsh_hdr_len(nsh_hdr);
+ skb_pull(skb, length);
+ skb_reset_mac_header(skb);
+ skb_reset_mac_len(skb);
+ skb_reset_network_header(skb);
+ skb->protocol = inner_proto;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(skb_pop_nsh);
+
static struct sk_buff *nsh_gso_segment(struct sk_buff *skb,
netdev_features_t features)
{
diff --git a/net/openvswitch/Kconfig b/net/openvswitch/Kconfig
index ce94729..2650205 100644
--- a/net/openvswitch/Kconfig
+++ b/net/openvswitch/Kconfig
@@ -14,6 +14,7 @@ config OPENVSWITCH
select MPLS
select NET_MPLS_GSO
select DST_CACHE
+ select NET_NSH
---help---
Open vSwitch is a multilayer Ethernet switch targeted at virtualized
environments. In addition to supporting a variety of features
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index a54a556..d026b85 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -43,6 +43,7 @@
#include "flow.h"
#include "conntrack.h"
#include "vport.h"
+#include "flow_netlink.h"
struct deferred_action {
struct sk_buff *skb;
@@ -380,6 +381,45 @@ static int push_eth(struct sk_buff *skb, struct sw_flow_key *key,
return 0;
}
+static int push_nsh(struct sk_buff *skb, struct sw_flow_key *key,
+ const struct nshhdr *src_nsh_hdr)
+{
+ int err;
+
+ err = skb_push_nsh(skb, src_nsh_hdr);
+ if (err)
+ return err;
+
+ key->eth.type = htons(ETH_P_NSH);
+
+ /* safe right before invalidate_flow_key */
+ key->mac_proto = MAC_PROTO_NONE;
+ invalidate_flow_key(key);
+ return 0;
+}
+
+static int pop_nsh(struct sk_buff *skb, struct sw_flow_key *key)
+{
+ int err;
+
+ if (ovs_key_mac_proto(key) != MAC_PROTO_NONE ||
+ skb->protocol != htons(ETH_P_NSH)) {
+ return -EINVAL;
+ }
+
+ err = skb_pop_nsh(skb);
+ if (err)
+ return err;
+
+ /* safe right before invalidate_flow_key */
+ if (skb->protocol == htons(ETH_P_TEB))
+ key->mac_proto = MAC_PROTO_ETHERNET;
+ else
+ key->mac_proto = MAC_PROTO_NONE;
+ invalidate_flow_key(key);
+ return 0;
+}
+
static void update_ip_l4_checksum(struct sk_buff *skb, struct iphdr *nh,
__be32 addr, __be32 new_addr)
{
@@ -602,6 +642,59 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *flow_key,
return 0;
}
+static int set_nsh(struct sk_buff *skb, struct sw_flow_key *flow_key,
+ const struct nlattr *a)
+{
+ struct nshhdr *nsh_hdr;
+ int err;
+ u8 flags;
+ u8 ttl;
+ int i;
+
+ struct ovs_key_nsh key;
+ struct ovs_key_nsh mask;
+
+ err = nsh_key_from_nlattr(a, &key, &mask);
+ if (err)
+ return err;
+
+ err = skb_ensure_writable(skb, skb_network_offset(skb) +
+ sizeof(struct nshhdr));
+ if (unlikely(err))
+ return err;
+
+ nsh_hdr = (struct nshhdr *)skb_network_header(skb);
+
+ flags = nsh_get_flags(nsh_hdr);
+ flags = OVS_MASKED(flags, key.flags, mask.flags);
+ flow_key->nsh.flags = flags;
+ ttl = nsh_get_ttl(nsh_hdr);
+ ttl = OVS_MASKED(ttl, key.ttl, mask.ttl);
+ flow_key->nsh.ttl = ttl;
+ nsh_set_flags_and_ttl(nsh_hdr, flags, ttl);
+ nsh_hdr->path_hdr = OVS_MASKED(nsh_hdr->path_hdr, key.path_hdr,
+ mask.path_hdr);
+ flow_key->nsh.path_hdr = nsh_hdr->path_hdr;
+ switch (nsh_hdr->mdtype) {
+ case NSH_M_TYPE1:
+ for (i = 0; i < NSH_MD1_CONTEXT_SIZE; i++) {
+ nsh_hdr->md1.context[i] =
+ OVS_MASKED(nsh_hdr->md1.context[i], key.context[i],
+ mask.context[i]);
+ }
+ memcpy(flow_key->nsh.context, nsh_hdr->md1.context,
+ sizeof(nsh_hdr->md1.context));
+ break;
+ case NSH_M_TYPE2:
+ memset(flow_key->nsh.context, 0,
+ sizeof(flow_key->nsh.context));
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
/* Must follow skb_ensure_writable() since that can move the skb data. */
static void set_tp_port(struct sk_buff *skb, __be16 *port,
__be16 new_port, __sum16 *check)
@@ -1024,6 +1117,10 @@ static int execute_masked_set_action(struct sk_buff *skb,
get_mask(a, struct ovs_key_ethernet *));
break;
+ case OVS_KEY_ATTR_NSH:
+ err = set_nsh(skb, flow_key, a);
+ break;
+
case OVS_KEY_ATTR_IPV4:
err = set_ipv4(skb, flow_key, nla_data(a),
get_mask(a, struct ovs_key_ipv4 *));
@@ -1210,6 +1307,21 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
case OVS_ACTION_ATTR_POP_ETH:
err = pop_eth(skb, key);
break;
+
+ case OVS_ACTION_ATTR_PUSH_NSH: {
+ u8 buffer[NSH_HDR_MAX_LEN];
+ struct nshhdr *nsh_hdr = (struct nshhdr *)buffer;
+ const struct nshhdr *src_nsh_hdr = nsh_hdr;
+
+ nsh_hdr_from_nlattr(nla_data(a), nsh_hdr,
+ NSH_HDR_MAX_LEN);
+ err = push_nsh(skb, key, src_nsh_hdr);
+ break;
+ }
+
+ case OVS_ACTION_ATTR_POP_NSH:
+ err = pop_nsh(skb, key);
+ break;
}
if (unlikely(err)) {
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 8c94cef..67fb6d9 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -46,6 +46,7 @@
#include <net/ipv6.h>
#include <net/mpls.h>
#include <net/ndisc.h>
+#include <net/nsh.h>
#include "conntrack.h"
#include "datapath.h"
@@ -490,6 +491,52 @@ static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key,
return 0;
}
+static int parse_nsh(struct sk_buff *skb, struct sw_flow_key *key)
+{
+ struct nshhdr *nsh_hdr;
+ unsigned int nh_ofs = skb_network_offset(skb);
+ u8 version, length;
+ int err;
+
+ err = check_header(skb, nh_ofs + NSH_BASE_HDR_LEN);
+ if (unlikely(err))
+ return err;
+
+ nsh_hdr = (struct nshhdr *)skb_network_header(skb);
+ version = nsh_get_ver(nsh_hdr);
+ length = nsh_hdr_len(nsh_hdr);
+
+ if (version != 0)
+ return -EINVAL;
+
+ err = check_header(skb, nh_ofs + length);
+ if (unlikely(err))
+ return err;
+
+ nsh_hdr = (struct nshhdr *)skb_network_header(skb);
+ key->nsh.flags = nsh_get_flags(nsh_hdr);
+ key->nsh.ttl = nsh_get_ttl(nsh_hdr);
+ key->nsh.mdtype = nsh_hdr->mdtype;
+ key->nsh.np = nsh_hdr->np;
+ key->nsh.path_hdr = nsh_hdr->path_hdr;
+ switch (key->nsh.mdtype) {
+ case NSH_M_TYPE1:
+ if (length != NSH_M_TYPE1_LEN)
+ return -EINVAL;
+ memcpy(key->nsh.context, nsh_hdr->md1.context,
+ sizeof(nsh_hdr->md1));
+ break;
+ case NSH_M_TYPE2:
+ memset(key->nsh.context, 0,
+ sizeof(nsh_hdr->md1));
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
/**
* key_extract - extracts a flow key from an Ethernet frame.
* @skb: sk_buff that contains the frame, with skb->data pointing to the
@@ -735,6 +782,10 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
memset(&key->tp, 0, sizeof(key->tp));
}
}
+ } else if (key->eth.type == htons(ETH_P_NSH)) {
+ error = parse_nsh(skb, key);
+ if (error)
+ return error;
}
return 0;
}
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h
index 1875bba..6a3cd9c 100644
--- a/net/openvswitch/flow.h
+++ b/net/openvswitch/flow.h
@@ -35,6 +35,7 @@
#include <net/inet_ecn.h>
#include <net/ip_tunnels.h>
#include <net/dst_metadata.h>
+#include <net/nsh.h>
struct sk_buff;
@@ -66,6 +67,15 @@ struct vlan_head {
(offsetof(struct sw_flow_key, recirc_id) + \
FIELD_SIZEOF(struct sw_flow_key, recirc_id))
+struct ovs_key_nsh {
+ u8 flags;
+ u8 ttl;
+ u8 mdtype;
+ u8 np;
+ __be32 path_hdr;
+ __be32 context[NSH_MD1_CONTEXT_SIZE];
+};
+
struct sw_flow_key {
u8 tun_opts[IP_TUNNEL_OPTS_MAX];
u8 tun_opts_len;
@@ -144,6 +154,7 @@ struct sw_flow_key {
};
} ipv6;
};
+ struct ovs_key_nsh nsh; /* network service header */
struct {
/* Connection tracking fields not packed above. */
struct {
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index e8eb427..278bbb3 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -48,6 +48,7 @@
#include <net/ndisc.h>
#include <net/mpls.h>
#include <net/vxlan.h>
+#include <net/tun_proto.h>
#include "flow_netlink.h"
@@ -78,9 +79,11 @@ static bool actions_may_change_flow(const struct nlattr *actions)
case OVS_ACTION_ATTR_HASH:
case OVS_ACTION_ATTR_POP_ETH:
case OVS_ACTION_ATTR_POP_MPLS:
+ case OVS_ACTION_ATTR_POP_NSH:
case OVS_ACTION_ATTR_POP_VLAN:
case OVS_ACTION_ATTR_PUSH_ETH:
case OVS_ACTION_ATTR_PUSH_MPLS:
+ case OVS_ACTION_ATTR_PUSH_NSH:
case OVS_ACTION_ATTR_PUSH_VLAN:
case OVS_ACTION_ATTR_SAMPLE:
case OVS_ACTION_ATTR_SET:
@@ -322,12 +325,27 @@ size_t ovs_tun_key_attr_size(void)
+ nla_total_size(2); /* OVS_TUNNEL_KEY_ATTR_TP_DST */
}
+size_t ovs_nsh_key_attr_size(void)
+{
+ /* Whenever adding new OVS_NSH_KEY_ FIELDS, we should consider
+ * updating this function.
+ */
+ return nla_total_size(NSH_BASE_HDR_LEN) /* OVS_NSH_KEY_ATTR_BASE */
+ /* OVS_NSH_KEY_ATTR_MD1 and OVS_NSH_KEY_ATTR_MD2 are
+ * mutually exclusive, so the bigger one can cover
+ * the small one.
+ *
+ * OVS_NSH_KEY_ATTR_MD2
+ */
+ + nla_total_size(NSH_CTX_HDRS_MAX_LEN);
+}
+
size_t ovs_key_attr_size(void)
{
/* Whenever adding new OVS_KEY_ FIELDS, we should consider
* updating this function.
*/
- BUILD_BUG_ON(OVS_KEY_ATTR_TUNNEL_INFO != 28);
+ BUILD_BUG_ON(OVS_KEY_ATTR_TUNNEL_INFO != 29);
return nla_total_size(4) /* OVS_KEY_ATTR_PRIORITY */
+ nla_total_size(0) /* OVS_KEY_ATTR_TUNNEL */
@@ -341,6 +359,8 @@ size_t ovs_key_attr_size(void)
+ nla_total_size(4) /* OVS_KEY_ATTR_CT_MARK */
+ nla_total_size(16) /* OVS_KEY_ATTR_CT_LABELS */
+ nla_total_size(40) /* OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6 */
+ + nla_total_size(0) /* OVS_KEY_ATTR_NSH */
+ + ovs_nsh_key_attr_size()
+ nla_total_size(12) /* OVS_KEY_ATTR_ETHERNET */
+ nla_total_size(2) /* OVS_KEY_ATTR_ETHERTYPE */
+ nla_total_size(4) /* OVS_KEY_ATTR_VLAN */
@@ -373,6 +393,13 @@ static const struct ovs_len_tbl ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1]
[OVS_TUNNEL_KEY_ATTR_IPV6_DST] = { .len = sizeof(struct in6_addr) },
};
+static const struct ovs_len_tbl
+ovs_nsh_key_attr_lens[OVS_NSH_KEY_ATTR_MAX + 1] = {
+ [OVS_NSH_KEY_ATTR_BASE] = { .len = sizeof(struct ovs_nsh_key_base) },
+ [OVS_NSH_KEY_ATTR_MD1] = { .len = sizeof(struct ovs_nsh_key_md1) },
+ [OVS_NSH_KEY_ATTR_MD2] = { .len = OVS_ATTR_VARIABLE },
+};
+
/* The size of the argument for each %OVS_KEY_ATTR_* Netlink attribute. */
static const struct ovs_len_tbl ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
[OVS_KEY_ATTR_ENCAP] = { .len = OVS_ATTR_NESTED },
@@ -405,6 +432,8 @@ static const struct ovs_len_tbl ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
.len = sizeof(struct ovs_key_ct_tuple_ipv4) },
[OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6] = {
.len = sizeof(struct ovs_key_ct_tuple_ipv6) },
+ [OVS_KEY_ATTR_NSH] = { .len = OVS_ATTR_NESTED,
+ .next = ovs_nsh_key_attr_lens, },
};
static bool check_attr_len(unsigned int attr_len, unsigned int expected_len)
@@ -1179,6 +1208,222 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
return 0;
}
+int nsh_hdr_from_nlattr(const struct nlattr *attr,
+ struct nshhdr *nsh, size_t size)
+{
+ struct nlattr *a;
+ int rem;
+ u8 flags = 0;
+ u8 ttl = 0;
+ int mdlen = 0;
+
+ /* validate_nsh has check this, so we needn't do duplicate check here
+ */
+ nla_for_each_nested(a, attr, rem) {
+ int type = nla_type(a);
+
+ switch (type) {
+ case OVS_NSH_KEY_ATTR_BASE: {
+ const struct ovs_nsh_key_base *base =
+ (struct ovs_nsh_key_base *)nla_data(a);
+ flags = base->flags;
+ ttl = base->ttl;
+ nsh->np = base->np;
+ nsh->mdtype = base->mdtype;
+ nsh->path_hdr = base->path_hdr;
+ break;
+ }
+ case OVS_NSH_KEY_ATTR_MD1: {
+ const struct ovs_nsh_key_md1 *md1 =
+ (struct ovs_nsh_key_md1 *)nla_data(a);
+ struct nsh_md1_ctx *md1_dst = &nsh->md1;
+
+ mdlen = nla_len(a);
+ memcpy(md1_dst, md1, mdlen);
+ break;
+ }
+ case OVS_NSH_KEY_ATTR_MD2: {
+ const struct u8 *md2 = nla_data(a);
+ struct nsh_md2_tlv *md2_dst = &nsh->md2;
+
+ mdlen = nla_len(a);
+ memcpy(md2_dst, md2, mdlen);
+ break;
+ }
+ default:
+ return -EINVAL;
+ }
+ }
+
+ /* nsh header length = NSH_BASE_HDR_LEN + mdlen */
+ nsh->ver_flags_ttl_len = 0;
+ nsh_set_flags_ttl_len(nsh, flags, ttl, NSH_BASE_HDR_LEN + mdlen);
+
+ return 0;
+}
+
+int nsh_key_from_nlattr(const struct nlattr *attr,
+ struct ovs_key_nsh *nsh, struct ovs_key_nsh *nsh_mask)
+{
+ struct nlattr *a;
+ int rem;
+
+ /* validate_nsh has check this, so we needn't do duplicate check here
+ */
+ nla_for_each_nested(a, attr, rem) {
+ int type = nla_type(a);
+
+ switch (type) {
+ case OVS_NSH_KEY_ATTR_BASE: {
+ const struct ovs_nsh_key_base *base =
+ (struct ovs_nsh_key_base *)nla_data(a);
+ const struct ovs_nsh_key_base *base_mask = base + 1;
+
+ memcpy(nsh, base, sizeof(*base));
+ memcpy(nsh, base_mask, sizeof(*base_mask));
+ break;
+ }
+ case OVS_NSH_KEY_ATTR_MD1: {
+ const struct ovs_nsh_key_md1 *md1 =
+ (struct ovs_nsh_key_md1 *)nla_data(a);
+ const struct ovs_nsh_key_md1 *md1_mask = md1 + 1;
+
+ memcpy(nsh->context, md1->context, sizeof(*md1));
+ memcpy(nsh_mask->context, md1_mask->context,
+ sizeof(*md1_mask));
+ break;
+ }
+ case OVS_NSH_KEY_ATTR_MD2:
+ /* Not supported yet */
+ return -ENOTSUPP;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static int nsh_key_put_from_nlattr(const struct nlattr *attr,
+ struct sw_flow_match *match, bool is_mask,
+ bool is_push_nsh, bool log)
+{
+ struct nlattr *a;
+ int rem;
+ bool has_base = false;
+ bool has_md1 = false;
+ bool has_md2 = false;
+ u8 mdtype = 0;
+ int mdlen = 0;
+
+ if (unlikely(is_push_nsh && is_mask))
+ return -EINVAL;
+
+ nla_for_each_nested(a, attr, rem) {
+ int type = nla_type(a);
+ int i;
+
+ if (type > OVS_NSH_KEY_ATTR_MAX) {
+ OVS_NLERR(log, "nsh attr %d is out of range max %d",
+ type, OVS_NSH_KEY_ATTR_MAX);
+ return -EINVAL;
+ }
+
+ if (!check_attr_len(nla_len(a),
+ ovs_nsh_key_attr_lens[type].len)) {
+ OVS_NLERR(
+ log,
+ "nsh attr %d has unexpected len %d expected %d",
+ type,
+ nla_len(a),
+ ovs_nsh_key_attr_lens[type].len
+ );
+ return -EINVAL;
+ }
+
+ switch (type) {
+ case OVS_NSH_KEY_ATTR_BASE: {
+ const struct ovs_nsh_key_base *base =
+ (struct ovs_nsh_key_base *)nla_data(a);
+
+ has_base = true;
+ mdtype = base->mdtype;
+ SW_FLOW_KEY_PUT(match, nsh.flags,
+ base->flags, is_mask);
+ SW_FLOW_KEY_PUT(match, nsh.ttl,
+ base->ttl, is_mask);
+ SW_FLOW_KEY_PUT(match, nsh.mdtype,
+ base->mdtype, is_mask);
+ SW_FLOW_KEY_PUT(match, nsh.np,
+ base->np, is_mask);
+ SW_FLOW_KEY_PUT(match, nsh.path_hdr,
+ base->path_hdr, is_mask);
+ break;
+ }
+ case OVS_NSH_KEY_ATTR_MD1: {
+ const struct ovs_nsh_key_md1 *md1 =
+ (struct ovs_nsh_key_md1 *)nla_data(a);
+
+ has_md1 = true;
+ for (i = 0; i < NSH_MD1_CONTEXT_SIZE; i++)
+ SW_FLOW_KEY_PUT(match, nsh.context[i],
+ md1->context[i], is_mask);
+ break;
+ }
+ case OVS_NSH_KEY_ATTR_MD2:
+ if (!is_push_nsh) /* Not supported MD type 2 yet */
+ return -ENOTSUPP;
+
+ has_md2 = true;
+ mdlen = nla_len(a);
+ if ((mdlen > NSH_CTX_HDRS_MAX_LEN) ||
+ (mdlen <= 0)) {
+ WARN_ON_ONCE(1);
+ return -EINVAL;
+ }
+ break;
+ default:
+ OVS_NLERR(log, "Unknown nsh attribute %d",
+ type);
+ return -EINVAL;
+ }
+ }
+
+ if (rem > 0) {
+ OVS_NLERR(log, "nsh attribute has %d unknown bytes.", rem);
+ return -EINVAL;
+ }
+
+ if (has_md1 && has_md2) {
+ OVS_NLERR(
+ 1,
+ "invalid nsh attribute: md1 and md2 are exclusive."
+ );
+ return -EINVAL;
+ }
+
+ if (!is_mask) {
+ if ((has_md1 && mdtype != NSH_M_TYPE1) ||
+ (has_md2 && mdtype != NSH_M_TYPE2)) {
+ OVS_NLERR(1, "nsh attribute has unmatched MD type %d.",
+ mdtype);
+ return -EINVAL;
+ }
+
+ if (is_push_nsh &&
+ (!has_base || (!has_md1 && !has_md2))) {
+ OVS_NLERR(
+ 1,
+ "push nsh attributes are invalid for type %d.",
+ mdtype
+ );
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int ovs_key_from_nlattrs(struct net *net, struct sw_flow_match *match,
u64 attrs, const struct nlattr **a,
bool is_mask, bool log)
@@ -1306,6 +1551,13 @@ static int ovs_key_from_nlattrs(struct net *net, struct sw_flow_match *match,
attrs &= ~(1 << OVS_KEY_ATTR_ARP);
}
+ if (attrs & (1 << OVS_KEY_ATTR_NSH)) {
+ if (nsh_key_put_from_nlattr(a[OVS_KEY_ATTR_NSH], match,
+ is_mask, false, log) < 0)
+ return -EINVAL;
+ attrs &= ~(1 << OVS_KEY_ATTR_NSH);
+ }
+
if (attrs & (1 << OVS_KEY_ATTR_MPLS)) {
const struct ovs_key_mpls *mpls_key;
@@ -1622,6 +1874,40 @@ static int ovs_nla_put_vlan(struct sk_buff *skb, const struct vlan_head *vh,
return 0;
}
+static int nsh_key_to_nlattr(const struct ovs_key_nsh *nsh, bool is_mask,
+ struct sk_buff *skb)
+{
+ struct nlattr *start;
+ struct ovs_nsh_key_base base;
+ struct ovs_nsh_key_md1 md1;
+
+ memcpy(&base, nsh, sizeof(base));
+
+ if (is_mask || nsh->mdtype == NSH_M_TYPE1)
+ memcpy(md1.context, nsh->context, sizeof(md1));
+
+ start = nla_nest_start(skb, OVS_KEY_ATTR_NSH);
+ if (!start)
+ return -EMSGSIZE;
+
+ if (nla_put(skb, OVS_NSH_KEY_ATTR_BASE, sizeof(base), &base))
+ goto nla_put_failure;
+
+ if (is_mask || nsh->mdtype == NSH_M_TYPE1) {
+ if (nla_put(skb, OVS_NSH_KEY_ATTR_MD1, sizeof(md1), &md1))
+ goto nla_put_failure;
+ }
+
+ /* Don't support MD type 2 yet */
+
+ nla_nest_end(skb, start);
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
static int __ovs_nla_put_key(const struct sw_flow_key *swkey,
const struct sw_flow_key *output, bool is_mask,
struct sk_buff *skb)
@@ -1750,6 +2036,9 @@ static int __ovs_nla_put_key(const struct sw_flow_key *swkey,
ipv6_key->ipv6_tclass = output->ip.tos;
ipv6_key->ipv6_hlimit = output->ip.ttl;
ipv6_key->ipv6_frag = output->ip.frag;
+ } else if (swkey->eth.type == htons(ETH_P_NSH)) {
+ if (nsh_key_to_nlattr(&output->nsh, is_mask, skb))
+ goto nla_put_failure;
} else if (swkey->eth.type == htons(ETH_P_ARP) ||
swkey->eth.type == htons(ETH_P_RARP)) {
struct ovs_key_arp *arp_key;
@@ -2242,6 +2531,19 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
return err;
}
+static bool validate_nsh(const struct nlattr *attr, bool is_mask,
+ bool is_push_nsh, bool log)
+{
+ struct sw_flow_match match;
+ struct sw_flow_key key;
+ int ret = 0;
+
+ ovs_match_init(&match, &key, true, NULL);
+ ret = nsh_key_put_from_nlattr(attr, &match, is_mask,
+ is_push_nsh, log);
+ return ((ret != 0) ? false : true);
+}
+
/* Return false if there are any non-masked bits set.
* Mask follows data immediately, before any netlink padding.
*/
@@ -2384,6 +2686,11 @@ static int validate_set(const struct nlattr *a,
break;
+ case OVS_KEY_ATTR_NSH:
+ if (!validate_nsh(nla_data(a), masked, false, log))
+ return -EINVAL;
+ break;
+
default:
return -EINVAL;
}
@@ -2482,6 +2789,8 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
[OVS_ACTION_ATTR_TRUNC] = sizeof(struct ovs_action_trunc),
[OVS_ACTION_ATTR_PUSH_ETH] = sizeof(struct ovs_action_push_eth),
[OVS_ACTION_ATTR_POP_ETH] = 0,
+ [OVS_ACTION_ATTR_PUSH_NSH] = (u32)-1,
+ [OVS_ACTION_ATTR_POP_NSH] = 0,
};
const struct ovs_action_push_vlan *vlan;
int type = nla_type(a);
@@ -2636,6 +2945,19 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
mac_proto = MAC_PROTO_ETHERNET;
break;
+ case OVS_ACTION_ATTR_PUSH_NSH:
+ mac_proto = MAC_PROTO_NONE;
+ if (!validate_nsh(nla_data(a), false, true, true))
+ return -EINVAL;
+ break;
+
+ case OVS_ACTION_ATTR_POP_NSH:
+ if (key->nsh.np == TUN_P_ETHERNET)
+ mac_proto = MAC_PROTO_ETHERNET;
+ else
+ mac_proto = MAC_PROTO_NONE;
+ break;
+
default:
OVS_NLERR(log, "Unknown Action type %d", type);
return -EINVAL;
diff --git a/net/openvswitch/flow_netlink.h b/net/openvswitch/flow_netlink.h
index 929c665..4b80083 100644
--- a/net/openvswitch/flow_netlink.h
+++ b/net/openvswitch/flow_netlink.h
@@ -79,4 +79,9 @@ int ovs_nla_put_actions(const struct nlattr *attr,
void ovs_nla_free_flow_actions(struct sw_flow_actions *);
void ovs_nla_free_flow_actions_rcu(struct sw_flow_actions *);
+int nsh_key_from_nlattr(const struct nlattr *attr, struct ovs_key_nsh *nsh,
+ struct ovs_key_nsh *nsh_mask);
+int nsh_hdr_from_nlattr(const struct nlattr *attr, struct nshhdr *src_nsh_hdr,
+ size_t size);
+
#endif /* flow_netlink.h */
--
2.5.5
^ permalink raw reply related
* Re: [patch net-next v2 06/12] net: mroute: Check if rule is a default rule
From: Yotam Gigi @ 2017-09-25 13:37 UTC (permalink / raw)
To: Nikolay Aleksandrov, Jiri Pirko, Yunsheng Lin
Cc: netdev, davem, idosch, mlxsw, andrew
In-Reply-To: <fc1f3324-d2fc-f95c-50d2-25773f3c7683@cumulusnetworks.com>
On 09/25/2017 01:02 PM, Nikolay Aleksandrov wrote:
> On 25/09/17 12:45, Jiri Pirko wrote:
>> Mon, Sep 25, 2017 at 03:28:21AM CEST, linyunsheng@huawei.com wrote:
>>> Hi, Jiri
>>>
>>> On 2017/9/25 1:22, Jiri Pirko wrote:
>>>> From: Yotam Gigi <yotamg@mellanox.com>
>>>>
>>>> When the ipmr starts, it adds one default FIB rule that matches all packets
>>>> and sends them to the DEFAULT (multicast) FIB table. A more complex rule
>>>> can be added by user to specify that for a specific interface, a packet
>>>> should be look up at either an arbitrary table or according to the l3mdev
>>>> of the interface.
>>>>
>>>> For drivers willing to offload the ipmr logic into a hardware but don't
>>>> want to offload all the FIB rules functionality, provide a function that
>>>> can indicate whether the FIB rule is the default multicast rule, thus only
>>>> one routing table is needed.
>>>>
>>>> This way, a driver can register to the FIB notification chain, get
>>>> notifications about FIB rules added and trigger some kind of an internal
>>>> abort mechanism when a non default rule is added by the user.
>>>>
>>>> Signed-off-by: Yotam Gigi <yotamg@mellanox.com>
>>>> Reviewed-by: Ido Schimmel <idosch@mellanox.com>
>>>> Signed-off-by: Jiri Pirko <jiri@mellanox.com>
>>>> ---
>>>> include/linux/mroute.h | 7 +++++++
>>>> net/ipv4/ipmr.c | 10 ++++++++++
>>>> 2 files changed, 17 insertions(+)
>>>>
>>>> diff --git a/include/linux/mroute.h b/include/linux/mroute.h
>>>> index 5566580..b072a84 100644
>>>> --- a/include/linux/mroute.h
>>>> +++ b/include/linux/mroute.h
>>>> @@ -5,6 +5,7 @@
>>>> #include <linux/pim.h>
>>>> #include <linux/rhashtable.h>
>>>> #include <net/sock.h>
>>>> +#include <net/fib_rules.h>
>>>> #include <net/fib_notifier.h>
>>>> #include <uapi/linux/mroute.h>
>>>>
>>>> @@ -19,6 +20,7 @@ int ip_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
>>>> int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg);
>>>> int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg);
>>>> int ip_mr_init(void);
>>>> +bool ipmr_rule_default(const struct fib_rule *rule);
>>>> #else
>>>> static inline int ip_mroute_setsockopt(struct sock *sock, int optname,
>>>> char __user *optval, unsigned int optlen)
>>>> @@ -46,6 +48,11 @@ static inline int ip_mroute_opt(int opt)
>>>> {
>>>> return 0;
>>>> }
>>>> +
>>>> +static inline bool ipmr_rule_default(const struct fib_rule *rule)
>>>> +{
>>>> + return true;
>>>> +}
>>>> #endif
>>>>
>>>> struct vif_device {
>>>> diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
>>>> index 2a795d2..a714f55 100644
>>>> --- a/net/ipv4/ipmr.c
>>>> +++ b/net/ipv4/ipmr.c
>>>> @@ -320,6 +320,16 @@ static unsigned int ipmr_rules_seq_read(struct net *net)
>>>> }
>>>> #endif
>>>>
>>>> +bool ipmr_rule_default(const struct fib_rule *rule)
>>>> +{
>>>> +#if IS_ENABLED(CONFIG_FIB_RULES)
>>>> + return fib_rule_matchall(rule) && rule->table == RT_TABLE_DEFAULT;
>>>> +#else
>>>> + return true;
>>>> +#endif
>>> In patch 02, You have the following, can you do the same for the above?
>>> +#ifdef CONFIG_IP_MROUTE
>>> +void ipmr_cache_free(struct mfc_cache *mfc_cache);
>>> +#else
>>> +static inline void ipmr_cache_free(struct mfc_cache *mfc_cache)
>>> +{
>>> +}
>>> +#endif
>> I don't believe this is necessary. The solution you described is often
>> used in headers. But here, I'm ok with the current code.
>>
> +1
Hmm, when re-looking at it, I think I will just use the already existing
#ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES other than adding a new one. It selects
the CONFIG_FIB_RULES, and if CONFIG_IP_MROUTE_MULTIPLE_TABLES is not defined
than only default rules can exist for the IPMR family.
I will fix it for v3.
>
>>>> +}
>>>> +EXPORT_SYMBOL(ipmr_rule_default);
>>>> +
>>>> static inline int ipmr_hash_cmp(struct rhashtable_compare_arg *arg,
>>>> const void *ptr)
>>>> {
>>>>
^ permalink raw reply
* Re: [PATCH net v2 1/3] net: mvpp2: fix parsing fragmentation detection
From: Antoine Tenart @ 2017-09-25 13:10 UTC (permalink / raw)
To: davem
Cc: Stefan Chulski, andrew, gregory.clement, thomas.petazzoni,
miquel.raynal, nadavh, linux, linux-kernel, mw, netdev,
Antoine Tenart
In-Reply-To: <20170925125948.13507-2-antoine.tenart@free-electrons.com>
On Mon, Sep 25, 2017 at 02:59:46PM +0200, Antoine Tenart wrote:
> From: Stefan Chulski <stefanc@marvell.com>
>
> Parsing fragmentation detection failed due to wrong configured
> parser TCAM entry's. Some traffic was marked as fragmented in RX
> descriptor, even it wasn't IP fragmented. The hardware also failed to
> calculate checksums which lead to use software checksum and caused
> performance degradation.
>
> Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit")
With,
Signed-off-by: Stefan Chulski <stefanc@marvell.com>
I don't know why this SoB was removed but it should be added back.
Antoine
> Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
> ---
> drivers/net/ethernet/marvell/mvpp2.c | 20 ++++++++++++++------
> 1 file changed, 14 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
> index dd0ee2691c86..da04939a2748 100644
> --- a/drivers/net/ethernet/marvell/mvpp2.c
> +++ b/drivers/net/ethernet/marvell/mvpp2.c
> @@ -676,6 +676,7 @@ enum mvpp2_tag_type {
> #define MVPP2_PRS_RI_L3_MCAST BIT(15)
> #define MVPP2_PRS_RI_L3_BCAST (BIT(15) | BIT(16))
> #define MVPP2_PRS_RI_IP_FRAG_MASK 0x20000
> +#define MVPP2_PRS_RI_IP_FRAG_TRUE BIT(17)
> #define MVPP2_PRS_RI_UDF3_MASK 0x300000
> #define MVPP2_PRS_RI_UDF3_RX_SPECIAL BIT(21)
> #define MVPP2_PRS_RI_L4_PROTO_MASK 0x1c00000
> @@ -2315,7 +2316,7 @@ static int mvpp2_prs_ip4_proto(struct mvpp2 *priv, unsigned short proto,
> (proto != IPPROTO_IGMP))
> return -EINVAL;
>
> - /* Fragmented packet */
> + /* Not fragmented packet */
> tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
> MVPP2_PE_LAST_FREE_TID);
> if (tid < 0)
> @@ -2334,8 +2335,12 @@ static int mvpp2_prs_ip4_proto(struct mvpp2 *priv, unsigned short proto,
> MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
> mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT,
> MVPP2_PRS_IPV4_DIP_AI_BIT);
> - mvpp2_prs_sram_ri_update(&pe, ri | MVPP2_PRS_RI_IP_FRAG_MASK,
> - ri_mask | MVPP2_PRS_RI_IP_FRAG_MASK);
> + mvpp2_prs_sram_ri_update(&pe, ri, ri_mask | MVPP2_PRS_RI_IP_FRAG_MASK);
> +
> + mvpp2_prs_tcam_data_byte_set(&pe, 2, 0x00,
> + MVPP2_PRS_TCAM_PROTO_MASK_L);
> + mvpp2_prs_tcam_data_byte_set(&pe, 3, 0x00,
> + MVPP2_PRS_TCAM_PROTO_MASK);
>
> mvpp2_prs_tcam_data_byte_set(&pe, 5, proto, MVPP2_PRS_TCAM_PROTO_MASK);
> mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV4_DIP_AI_BIT);
> @@ -2346,7 +2351,7 @@ static int mvpp2_prs_ip4_proto(struct mvpp2 *priv, unsigned short proto,
> mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);
> mvpp2_prs_hw_write(priv, &pe);
>
> - /* Not fragmented packet */
> + /* Fragmented packet */
> tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
> MVPP2_PE_LAST_FREE_TID);
> if (tid < 0)
> @@ -2358,8 +2363,11 @@ static int mvpp2_prs_ip4_proto(struct mvpp2 *priv, unsigned short proto,
> pe.sram.word[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0;
> mvpp2_prs_sram_ri_update(&pe, ri, ri_mask);
>
> - mvpp2_prs_tcam_data_byte_set(&pe, 2, 0x00, MVPP2_PRS_TCAM_PROTO_MASK_L);
> - mvpp2_prs_tcam_data_byte_set(&pe, 3, 0x00, MVPP2_PRS_TCAM_PROTO_MASK);
> + mvpp2_prs_sram_ri_update(&pe, ri | MVPP2_PRS_RI_IP_FRAG_TRUE,
> + ri_mask | MVPP2_PRS_RI_IP_FRAG_MASK);
> +
> + mvpp2_prs_tcam_data_byte_set(&pe, 2, 0x00, 0x0);
> + mvpp2_prs_tcam_data_byte_set(&pe, 3, 0x00, 0x0);
>
> /* Update shadow table and hw entry */
> mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);
> --
> 2.13.5
>
--
Antoine Ténart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* Re: [PATCH net v2 2/3] net: mvpp2: fix port list indexing
From: Antoine Tenart @ 2017-09-25 13:09 UTC (permalink / raw)
To: davem
Cc: Yan Markman, andrew, gregory.clement, thomas.petazzoni,
miquel.raynal, nadavh, linux, linux-kernel, mw, stefanc, netdev,
Antoine Tenart
In-Reply-To: <20170925125948.13507-3-antoine.tenart@free-electrons.com>
On Mon, Sep 25, 2017 at 02:59:47PM +0200, Antoine Tenart wrote:
> From: Yan Markman <ymarkman@marvell.com>
>
> The private port_list array has a list of pointers to mvpp2_port
> instances. This list is allocated given the number of ports enabled in
> the device tree, but the pointers are set using the port-id property. If
> on a single port is enabled, the port_list array will be of size 1, but
> when registering the port, if its id is not 0 the driver will crash.
> Other crashes were encountered in various situations.
>
> This fixes the issue by using an index not equal to the value of the
> port-id property.
>
> Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit")
With,
Signed-off-by: Yan Markman <ymarkman@marvell.com>
I don't know why it was removed, but this SoB should be added back.
Antoine
> Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
> ---
> drivers/net/ethernet/marvell/mvpp2.c | 8 +++++---
> 1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
> index da04939a2748..b2f99df81e9c 100644
> --- a/drivers/net/ethernet/marvell/mvpp2.c
> +++ b/drivers/net/ethernet/marvell/mvpp2.c
> @@ -7504,7 +7504,7 @@ static void mvpp2_port_copy_mac_addr(struct net_device *dev, struct mvpp2 *priv,
> /* Ports initialization */
> static int mvpp2_port_probe(struct platform_device *pdev,
> struct device_node *port_node,
> - struct mvpp2 *priv)
> + struct mvpp2 *priv, int index)
> {
> struct device_node *phy_node;
> struct phy *comphy;
> @@ -7678,7 +7678,7 @@ static int mvpp2_port_probe(struct platform_device *pdev,
> }
> netdev_info(dev, "Using %s mac address %pM\n", mac_from, dev->dev_addr);
>
> - priv->port_list[id] = port;
> + priv->port_list[index] = port;
> return 0;
>
> err_free_port_pcpu:
> @@ -8013,10 +8013,12 @@ static int mvpp2_probe(struct platform_device *pdev)
> }
>
> /* Initialize ports */
> + i = 0;
> for_each_available_child_of_node(dn, port_node) {
> - err = mvpp2_port_probe(pdev, port_node, priv);
> + err = mvpp2_port_probe(pdev, port_node, priv, i);
> if (err < 0)
> goto err_mg_clk;
> + i++;
> }
>
> platform_set_drvdata(pdev, priv);
> --
> 2.13.5
>
--
Antoine Ténart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* Re: [PATCH net-next] net: mvpp2: phylink support
From: Antoine Tenart @ 2017-09-25 13:06 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: Antoine Tenart, davem, andrew, gregory.clement, thomas.petazzoni,
miquel.raynal, nadavh, linux-kernel, mw, stefanc, netdev
In-Reply-To: <20170925121343.GO20805@n2100.armlinux.org.uk>
On Mon, Sep 25, 2017 at 01:13:43PM +0100, Russell King - ARM Linux wrote:
> On Mon, Sep 25, 2017 at 01:53:03PM +0200, Antoine Tenart wrote:
> > On Mon, Sep 25, 2017 at 11:45:32AM +0100, Russell King - ARM Linux wrote:
> > > Can you describe what the GoP link IRQ is doing please?
> >
> > In cases where there is no PHY connected to the MAC and no SFP cage is
> > used. One example is when a SOHO switch is connected directly to a
> > serdes lane. In such cases we still need to have a minimal link
> > management. The GoP link interrupt helps doing so as it raises when the
> > serdes is in sync and AN succeeded.
>
> Isn't this just like a fixed link scenario, or an in-band
> autonegotiation scenario (both of which phylink supports natively)?
>
> The situation on Clearfog with the 88E6176 switch is pretty similar -
> a switch connected directly via serdes to the MAC. Currently, we
> configure stuff there as a fixed link, but in actual fact the 88E6176
> is configured to run the CPU facing port in 1000base-X mode, and with
> appropriate tweaks, switching phylink to 1000base-X mode also works.
Hmm, I think you're right, we should be able to represent the link
between the MAC and the switch as a fixed link. And when it's not fixed,
it could be done with in-band AN. I cannot test this myself but I've
asked someone who can to.
Antoine
--
Antoine Ténart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* [PATCH net v2 3/3] net: mvpp2: do not select the internal source clock
From: Antoine Tenart @ 2017-09-25 12:59 UTC (permalink / raw)
To: davem
Cc: Antoine Tenart, andrew, gregory.clement, thomas.petazzoni,
miquel.raynal, nadavh, linux, linux-kernel, mw, stefanc, netdev
In-Reply-To: <20170925125948.13507-1-antoine.tenart@free-electrons.com>
This patch stops the internal MAC Tx clock from being enabled as the
internal clock isn't used. The definition used for the bit controlling
this behaviour is renamed as well as it was wrongly named (bit 4 of
GMAC_CTRL_2_REG).
Fixes: 3919357fb0bb ("net: mvpp2: initialize the GMAC when using a port")
Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
drivers/net/ethernet/marvell/mvpp2.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index b2f99df81e9c..161055564720 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -333,7 +333,7 @@
#define MVPP2_GMAC_INBAND_AN_MASK BIT(0)
#define MVPP2_GMAC_FLOW_CTRL_MASK GENMASK(2, 1)
#define MVPP2_GMAC_PCS_ENABLE_MASK BIT(3)
-#define MVPP2_GMAC_PORT_RGMII_MASK BIT(4)
+#define MVPP2_GMAC_INTERNAL_CLK_MASK BIT(4)
#define MVPP2_GMAC_DISABLE_PADDING BIT(5)
#define MVPP2_GMAC_PORT_RESET_MASK BIT(6)
#define MVPP2_GMAC_AUTONEG_CONFIG 0xc
@@ -4599,7 +4599,6 @@ static void mvpp2_port_mii_gmac_configure(struct mvpp2_port *port)
val |= MVPP2_GMAC_INBAND_AN_MASK | MVPP2_GMAC_PCS_ENABLE_MASK;
} else if (phy_interface_mode_is_rgmii(port->phy_interface)) {
val &= ~MVPP2_GMAC_PCS_ENABLE_MASK;
- val |= MVPP2_GMAC_PORT_RGMII_MASK;
}
writel(val, port->base + MVPP2_GMAC_CTRL_2_REG);
--
2.13.5
^ permalink raw reply related
* [PATCH net v2 2/3] net: mvpp2: fix port list indexing
From: Antoine Tenart @ 2017-09-25 12:59 UTC (permalink / raw)
To: davem
Cc: Yan Markman, andrew, gregory.clement, thomas.petazzoni,
miquel.raynal, nadavh, linux, linux-kernel, mw, stefanc, netdev,
Antoine Tenart
In-Reply-To: <20170925125948.13507-1-antoine.tenart@free-electrons.com>
From: Yan Markman <ymarkman@marvell.com>
The private port_list array has a list of pointers to mvpp2_port
instances. This list is allocated given the number of ports enabled in
the device tree, but the pointers are set using the port-id property. If
on a single port is enabled, the port_list array will be of size 1, but
when registering the port, if its id is not 0 the driver will crash.
Other crashes were encountered in various situations.
This fixes the issue by using an index not equal to the value of the
port-id property.
Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit")
Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
drivers/net/ethernet/marvell/mvpp2.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index da04939a2748..b2f99df81e9c 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -7504,7 +7504,7 @@ static void mvpp2_port_copy_mac_addr(struct net_device *dev, struct mvpp2 *priv,
/* Ports initialization */
static int mvpp2_port_probe(struct platform_device *pdev,
struct device_node *port_node,
- struct mvpp2 *priv)
+ struct mvpp2 *priv, int index)
{
struct device_node *phy_node;
struct phy *comphy;
@@ -7678,7 +7678,7 @@ static int mvpp2_port_probe(struct platform_device *pdev,
}
netdev_info(dev, "Using %s mac address %pM\n", mac_from, dev->dev_addr);
- priv->port_list[id] = port;
+ priv->port_list[index] = port;
return 0;
err_free_port_pcpu:
@@ -8013,10 +8013,12 @@ static int mvpp2_probe(struct platform_device *pdev)
}
/* Initialize ports */
+ i = 0;
for_each_available_child_of_node(dn, port_node) {
- err = mvpp2_port_probe(pdev, port_node, priv);
+ err = mvpp2_port_probe(pdev, port_node, priv, i);
if (err < 0)
goto err_mg_clk;
+ i++;
}
platform_set_drvdata(pdev, priv);
--
2.13.5
^ permalink raw reply related
* [PATCH net v2 1/3] net: mvpp2: fix parsing fragmentation detection
From: Antoine Tenart @ 2017-09-25 12:59 UTC (permalink / raw)
To: davem
Cc: Stefan Chulski, andrew, gregory.clement, thomas.petazzoni,
miquel.raynal, nadavh, linux, linux-kernel, mw, netdev,
Antoine Tenart
In-Reply-To: <20170925125948.13507-1-antoine.tenart@free-electrons.com>
From: Stefan Chulski <stefanc@marvell.com>
Parsing fragmentation detection failed due to wrong configured
parser TCAM entry's. Some traffic was marked as fragmented in RX
descriptor, even it wasn't IP fragmented. The hardware also failed to
calculate checksums which lead to use software checksum and caused
performance degradation.
Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit")
Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
drivers/net/ethernet/marvell/mvpp2.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index dd0ee2691c86..da04939a2748 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -676,6 +676,7 @@ enum mvpp2_tag_type {
#define MVPP2_PRS_RI_L3_MCAST BIT(15)
#define MVPP2_PRS_RI_L3_BCAST (BIT(15) | BIT(16))
#define MVPP2_PRS_RI_IP_FRAG_MASK 0x20000
+#define MVPP2_PRS_RI_IP_FRAG_TRUE BIT(17)
#define MVPP2_PRS_RI_UDF3_MASK 0x300000
#define MVPP2_PRS_RI_UDF3_RX_SPECIAL BIT(21)
#define MVPP2_PRS_RI_L4_PROTO_MASK 0x1c00000
@@ -2315,7 +2316,7 @@ static int mvpp2_prs_ip4_proto(struct mvpp2 *priv, unsigned short proto,
(proto != IPPROTO_IGMP))
return -EINVAL;
- /* Fragmented packet */
+ /* Not fragmented packet */
tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
MVPP2_PE_LAST_FREE_TID);
if (tid < 0)
@@ -2334,8 +2335,12 @@ static int mvpp2_prs_ip4_proto(struct mvpp2 *priv, unsigned short proto,
MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT,
MVPP2_PRS_IPV4_DIP_AI_BIT);
- mvpp2_prs_sram_ri_update(&pe, ri | MVPP2_PRS_RI_IP_FRAG_MASK,
- ri_mask | MVPP2_PRS_RI_IP_FRAG_MASK);
+ mvpp2_prs_sram_ri_update(&pe, ri, ri_mask | MVPP2_PRS_RI_IP_FRAG_MASK);
+
+ mvpp2_prs_tcam_data_byte_set(&pe, 2, 0x00,
+ MVPP2_PRS_TCAM_PROTO_MASK_L);
+ mvpp2_prs_tcam_data_byte_set(&pe, 3, 0x00,
+ MVPP2_PRS_TCAM_PROTO_MASK);
mvpp2_prs_tcam_data_byte_set(&pe, 5, proto, MVPP2_PRS_TCAM_PROTO_MASK);
mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV4_DIP_AI_BIT);
@@ -2346,7 +2351,7 @@ static int mvpp2_prs_ip4_proto(struct mvpp2 *priv, unsigned short proto,
mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);
mvpp2_prs_hw_write(priv, &pe);
- /* Not fragmented packet */
+ /* Fragmented packet */
tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
MVPP2_PE_LAST_FREE_TID);
if (tid < 0)
@@ -2358,8 +2363,11 @@ static int mvpp2_prs_ip4_proto(struct mvpp2 *priv, unsigned short proto,
pe.sram.word[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0;
mvpp2_prs_sram_ri_update(&pe, ri, ri_mask);
- mvpp2_prs_tcam_data_byte_set(&pe, 2, 0x00, MVPP2_PRS_TCAM_PROTO_MASK_L);
- mvpp2_prs_tcam_data_byte_set(&pe, 3, 0x00, MVPP2_PRS_TCAM_PROTO_MASK);
+ mvpp2_prs_sram_ri_update(&pe, ri | MVPP2_PRS_RI_IP_FRAG_TRUE,
+ ri_mask | MVPP2_PRS_RI_IP_FRAG_MASK);
+
+ mvpp2_prs_tcam_data_byte_set(&pe, 2, 0x00, 0x0);
+ mvpp2_prs_tcam_data_byte_set(&pe, 3, 0x00, 0x0);
/* Update shadow table and hw entry */
mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);
--
2.13.5
^ permalink raw reply related
* [PATCH net v2 0/3] net: mvpp2: various fixes
From: Antoine Tenart @ 2017-09-25 12:59 UTC (permalink / raw)
To: davem
Cc: Antoine Tenart, andrew, gregory.clement, thomas.petazzoni,
miquel.raynal, nadavh, linux, linux-kernel, mw, stefanc, netdev
Hi all,
This series contains 3 fixes for the Marvell PPv2 driver.
Thanks!
Antoine
Since v1:
- Removed one patch about dma masks as it would need a better fix.
- Added one fix about the MAC Tx clock source selection.
Antoine Tenart (1):
net: mvpp2: do not select the internal source clock
Stefan Chulski (1):
net: mvpp2: fix parsing fragmentation detection
Yan Markman (1):
net: mvpp2: fix port list indexing
drivers/net/ethernet/marvell/mvpp2.c | 31 ++++++++++++++++++++-----------
1 file changed, 20 insertions(+), 11 deletions(-)
--
2.13.5
^ permalink raw reply
* Re: [PATCH net 1/3] net: mvpp2: fix the dma_mask and coherent_dma_mask settings for PPv2.2
From: Antoine Tenart @ 2017-09-25 12:40 UTC (permalink / raw)
To: David Miller
Cc: antoine.tenart, andrew, gregory.clement, thomas.petazzoni,
miquel.raynal, nadavh, linux, linux-kernel, mw, stefanc, netdev
In-Reply-To: <20170921.100718.386894052177530033.davem@davemloft.net>
On Thu, Sep 21, 2017 at 10:07:18AM -0700, David Miller wrote:
> From: Antoine Tenart <antoine.tenart@free-electrons.com>
> Date: Thu, 21 Sep 2017 16:24:13 +0200
>
> > That's also the default when the platform does not allocate dma_mask.
>
> That's the problem that needs to be fixed then.
OK, I'll drop this patch until I find a proper solution.
Thanks,
Antoine
--
Antoine Ténart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* Re: [PATCH net v2] l2tp: fix race condition in l2tp_tunnel_delete
From: Guillaume Nault @ 2017-09-25 12:33 UTC (permalink / raw)
To: Sabrina Dubroca; +Cc: netdev, Xin Long, Tom Parkin
In-Reply-To: <20170922161624.GA31500@bistromath.localdomain>
On Fri, Sep 22, 2017 at 06:16:24PM +0200, Sabrina Dubroca wrote:
> 2017-09-19, 18:43:37 +0200, Guillaume Nault wrote:
> > On Tue, Sep 19, 2017 at 03:40:40PM +0200, Sabrina Dubroca wrote:
> > > If we try to delete the same tunnel twice, the first delete operation
> > > does a lookup (l2tp_tunnel_get), finds the tunnel, calls
> > > l2tp_tunnel_delete, which queues it for deletion by
> > > l2tp_tunnel_del_work.
> > >
> > > The second delete operation also finds the tunnel and calls
> > > l2tp_tunnel_delete. If the workqueue has already fired and started
> > > running l2tp_tunnel_del_work, then l2tp_tunnel_delete will queue the
> > > same tunnel a second time, and try to free the socket again.
> > >
> > > Add a dead flag to prevent firing the workqueue twice. Then we can
> > > remove the check of queue_work's result that was meant to prevent that
> > > race but doesn't.
> > >
> > > Also check the flag in the tunnel lookup functions, to avoid returning a
> > > tunnel that is already scheduled for destruction.
> > >
> > > Reproducer:
> > >
> > > ip l2tp add tunnel tunnel_id 3000 peer_tunnel_id 4000 local 192.168.0.2 remote 192.168.0.1 encap udp udp_sport 5000 udp_dport 6000
> > > ip l2tp add session name l2tp1 tunnel_id 3000 session_id 1000 peer_session_id 2000
> > > ip link set l2tp1 up
> > > ip l2tp del tunnel tunnel_id 3000
> > > ip l2tp del tunnel tunnel_id 3000
> > >
> > > Fixes: f8ccac0e4493 ("l2tp: put tunnel socket release on a workqueue")
> > > Reported-by: Jianlin Shi <jishi@redhat.com>
> > > Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
> > > ---
> > > v2: as Tom Parkin explained, we can't remove the tunnel from the
> > > per-net list from netlink. v2 uses only a dead flag, and adds
> > > corresponding checks during lookups
> > >
> > > net/l2tp/l2tp_core.c | 18 +++++++++---------
> > > net/l2tp/l2tp_core.h | 5 ++++-
> > > 2 files changed, 13 insertions(+), 10 deletions(-)
> > >
> > > diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
> > > index ee485df73ccd..3891f0260f2b 100644
> > > --- a/net/l2tp/l2tp_core.c
> > > +++ b/net/l2tp/l2tp_core.c
> > > @@ -203,7 +203,8 @@ struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id)
> > >
> > > rcu_read_lock_bh();
> > > list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
> > > - if (tunnel->tunnel_id == tunnel_id) {
> > > + if (tunnel->tunnel_id == tunnel_id &&
> > > + !test_bit(0, &tunnel->dead)) {
> > > l2tp_tunnel_inc_refcount(tunnel);
> > > rcu_read_unlock_bh();
> > >
> > > @@ -390,7 +391,8 @@ struct l2tp_tunnel *l2tp_tunnel_find(const struct net *net, u32 tunnel_id)
> > >
> > > rcu_read_lock_bh();
> > > list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
> > > - if (tunnel->tunnel_id == tunnel_id) {
> > > + if (tunnel->tunnel_id == tunnel_id &&
> > > + !test_bit(0, &tunnel->dead)) {
> > > rcu_read_unlock_bh();
> > > return tunnel;
> > > }
> > > @@ -409,7 +411,7 @@ struct l2tp_tunnel *l2tp_tunnel_find_nth(const struct net *net, int nth)
> > >
> > > rcu_read_lock_bh();
> > > list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
> > > - if (++count > nth) {
> > > + if (++count > nth && !test_bit(0, &tunnel->dead)) {
> > > rcu_read_unlock_bh();
> > > return tunnel;
> > > }
> > >
> > I don't get why you're checking the dead flag in l2tp_tunnel_{get,find}*().
> > Since it can be set concurrently right after test_bit(), it doesn't
> > protect the caller from getting a tunnel that is being removed by
> > l2tp_tunnel_delete().
> > Or have I missed something?
>
> You're right.
>
> Then I would try going back to essentially v1, but keeping code to
> remove the tunnel from the list in l2tp_tunnel_destruct if it's not
> dead yet.
>
> What do you think?
>
My main question was more about why do you feel the need for preventing
other parts of the code from accessing dead tunnels? The TOCTOU issue
was just there to illustrate the fact that it couldn't be implemented
this easily.
My reasonning is that a tunnel may already be in use when
l2tp_tunnel_delete() is called. So any function using tunnels must
already work properly on dying tunnels, because l2tp_tunnel_delete()
might kill them concurrently. Getting a dying tunnel from
l2tp_tunnel_get() or having the tunnel killed by l2tp_tunnel_delete()
while in use should make no difference, as long as the user properly
holds a reference. Of course we have the problem of l2tp_tunnel_find*()
which is racy wrt. tunnel reference counting, but I'm going to continue
converting these users to the safe l2tp_tunnel_get() lookup function.
Of course, making dying tunnels inaccessible makes sense but, unless
I've missed something, it looks more like cleanup/optimisation than bug
fixing.
So what about using your v2 patch, but without the ->dead flag test in
l2tp_tunnel_get() and l2tp_tunnel_find*()?
Now for some more context, I think tunnel creation and deletion will
need to be reworked. Tunnels should be removed from the pernet list by
l2tp_udp_encap_destroy() for L2TP over UDP, and by
l2tp_ip_destroy_sock() or l2tp_ip6_destroy_sock() for L2TP over IP.
Then we could stop hooking on ->sk_destruct(), because the
l2tp_tunnel_closeall() call found in l2tp_tunnel_destruct() is already
useless (if it actually had to remove sessions, it could sleep while in
atomic context, because ->sk_destruct() is now invoked through
call_rcu() for UDP sockets).
And we should break the tight coupling of the l2tp_tunnel structure
with the tunnel socket. This situation, where they dereference one
another without any protection, complicates the deletion process.
Protecting the socket and the tunnel's structure pointers with RCU
would certainly allow for simpler deletion code.
All in all, your last patch makes a lot of sense in this bigger
picture, but for now I'd rather go for simply preventing queueing
l2tp_tunnel_del_work() twice. Unless required for accurately fixing the
current issue, I think removing tunnels in l2tp_tunnel_delete() would fit
better in a different series.
>
> -------- 8< --------
>
> diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
> index ee485df73ccd..63cd1f30ac7d 100644
> --- a/net/l2tp/l2tp_core.c
> +++ b/net/l2tp/l2tp_core.c
> @@ -1234,6 +1234,23 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
> }
> EXPORT_SYMBOL_GPL(l2tp_xmit_skb);
>
> +static bool __l2tp_tunnel_delete(struct l2tp_tunnel *tunnel)
> +{
> + struct l2tp_net *pn = l2tp_pernet(tunnel->l2tp_net);
> + bool ret = false;
> +
> + spin_lock_bh(&pn->l2tp_tunnel_list_lock);
> + if (!tunnel->dead) {
> + tunnel->dead = 1;
> + list_del_rcu(&tunnel->list);
> + atomic_dec(&l2tp_tunnel_count);
> + ret = true;
> + }
> + spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
> +
> + return ret;
> +}
> +
> /*****************************************************************************
> * Tinnel and session create/destroy.
> *****************************************************************************/
> @@ -1245,7 +1262,6 @@ EXPORT_SYMBOL_GPL(l2tp_xmit_skb);
> static void l2tp_tunnel_destruct(struct sock *sk)
> {
> struct l2tp_tunnel *tunnel = l2tp_tunnel(sk);
> - struct l2tp_net *pn;
>
> if (tunnel == NULL)
> goto end;
> @@ -1270,11 +1286,7 @@ static void l2tp_tunnel_destruct(struct sock *sk)
> sk->sk_user_data = NULL;
>
> /* Remove the tunnel struct from the tunnel list */
> - pn = l2tp_pernet(tunnel->l2tp_net);
> - spin_lock_bh(&pn->l2tp_tunnel_list_lock);
> - list_del_rcu(&tunnel->list);
> - spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
> - atomic_dec(&l2tp_tunnel_count);
> + __l2tp_tunnel_delete(tunnel);
>
> l2tp_tunnel_closeall(tunnel);
>
> @@ -1685,14 +1697,12 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_create);
>
> /* This function is used by the netlink TUNNEL_DELETE command.
> */
> -int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel)
> +void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel)
> {
> - l2tp_tunnel_inc_refcount(tunnel);
> - if (false == queue_work(l2tp_wq, &tunnel->del_work)) {
> - l2tp_tunnel_dec_refcount(tunnel);
> - return 1;
> + if (__l2tp_tunnel_delete(tunnel)) {
> + l2tp_tunnel_inc_refcount(tunnel);
> + queue_work(l2tp_wq, &tunnel->del_work);
> }
> - return 0;
> }
> EXPORT_SYMBOL_GPL(l2tp_tunnel_delete);
>
> diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
> index a305e0c5925a..173e68bb8119 100644
> --- a/net/l2tp/l2tp_core.h
> +++ b/net/l2tp/l2tp_core.h
> @@ -160,6 +160,8 @@ struct l2tp_tunnel_cfg {
>
> struct l2tp_tunnel {
> int magic; /* Should be L2TP_TUNNEL_MAGIC */
> + int dead;
> +
> struct rcu_head rcu;
> rwlock_t hlist_lock; /* protect session_hlist */
> bool acpt_newsess; /* Indicates whether this
> @@ -254,7 +256,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id,
> u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg,
> struct l2tp_tunnel **tunnelp);
> void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel);
> -int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel);
> +void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel);
> struct l2tp_session *l2tp_session_create(int priv_size,
> struct l2tp_tunnel *tunnel,
> u32 session_id, u32 peer_session_id,
>
>
> --
> Sabrina
^ permalink raw reply
* Re: usb/wireless/rsi_91x: use-after-free write in __run_timers
From: Kalle Valo @ 2017-09-25 12:26 UTC (permalink / raw)
To: Andrey Konovalov
Cc: Amitkumar Karwar, Prameela Rani Garnepudi, Karun Eagalapati,
linux-wireless, netdev, LKML, Dmitry Vyukov, Kostya Serebryany,
syzkaller
In-Reply-To: <CAAeHK+y61FFKLpePKOhRjd=5QJEWRy9-pank64PuG+aKzafANw@mail.gmail.com>
Andrey Konovalov <andreyknvl@google.com> writes:
> On Mon, Sep 25, 2017 at 6:26 AM, Kalle Valo <kvalo@codeaurora.org> wrote:
>> Andrey Konovalov <andreyknvl@google.com> writes:
>>
>>> I've got the following report while fuzzing the kernel with syzkaller.
>>>
>>> On commit 6e80ecdddf4ea6f3cd84e83720f3d852e6624a68 (Sep 21).
>>>
>>> ==================================================================
>>> BUG: KASAN: use-after-free in __run_timers+0xc0e/0xd40
>>> Write of size 8 at addr ffff880069f701b8 by task swapper/0/0
>>>
>>> CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.14.0-rc1-42311-g6e80ecdddf4e #234
>>> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
>>
>> [...]
>>
>>> Allocated by task 1845:
>>> save_stack_trace+0x1b/0x20 arch/x86/kernel/stacktrace.c:59
>>> save_stack+0x43/0xd0 mm/kasan/kasan.c:447
>>> set_track mm/kasan/kasan.c:459
>>> kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:551
>>> kmem_cache_alloc_trace+0x11e/0x2d0 mm/slub.c:2772
>>> kmalloc ./include/linux/slab.h:493
>>> kzalloc ./include/linux/slab.h:666
>>> rsi_91x_init+0x98/0x510 drivers/net/wireless/rsi/rsi_91x_main.c:203
>>> rsi_probe+0xb6/0x13b0 drivers/net/wireless/rsi/rsi_91x_usb.c:665
>>> usb_probe_interface+0x35d/0x8e0 drivers/usb/core/driver.c:361
>>
>> I'm curious about your setup. Apparently you are running syzkaller on
>> QEMU but what I don't understand is how the rsi device comes into the
>> picture. Did you have a rsi usb device connected to the virtual machine
>> or what? Or does syzkaller do some kind of magic here?
>
> I use dummy_hcd and gadgetfs to connect random USB devices to the
> kernel from a userspace application. This happens inside a QEMU
> instance. This simplifies fuzzing, since everything is virtualized,
> but the found bugs can be triggered on a real machine by connecting a
> malicious USB device.
That's very cool, thanks for explaining the setup.
--
Kalle Valo
^ permalink raw reply
* Re: [PATCH net-next] net: mvpp2: phylink support
From: Russell King - ARM Linux @ 2017-09-25 12:13 UTC (permalink / raw)
To: Antoine Tenart
Cc: davem, andrew, gregory.clement, thomas.petazzoni, miquel.raynal,
nadavh, linux-kernel, mw, stefanc, netdev
In-Reply-To: <20170925115303.GC19364@kwain>
On Mon, Sep 25, 2017 at 01:53:03PM +0200, Antoine Tenart wrote:
> On Mon, Sep 25, 2017 at 11:45:32AM +0100, Russell King - ARM Linux wrote:
> > Can you describe what the GoP link IRQ is doing please?
>
> In cases where there is no PHY connected to the MAC and no SFP cage is
> used. One example is when a SOHO switch is connected directly to a
> serdes lane. In such cases we still need to have a minimal link
> management. The GoP link interrupt helps doing so as it raises when the
> serdes is in sync and AN succeeded.
Isn't this just like a fixed link scenario, or an in-band
autonegotiation scenario (both of which phylink supports natively)?
The situation on Clearfog with the 88E6176 switch is pretty similar -
a switch connected directly via serdes to the MAC. Currently, we
configure stuff there as a fixed link, but in actual fact the 88E6176
is configured to run the CPU facing port in 1000base-X mode, and with
appropriate tweaks, switching phylink to 1000base-X mode also works.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up
^ permalink raw reply
* Re: [PATCH net-next] net: mvpp2: phylink support
From: Antoine Tenart @ 2017-09-25 11:53 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: Antoine Tenart, davem, andrew, gregory.clement, thomas.petazzoni,
miquel.raynal, nadavh, linux-kernel, mw, stefanc, netdev
In-Reply-To: <20170925104532.GN20805@n2100.armlinux.org.uk>
On Mon, Sep 25, 2017 at 11:45:32AM +0100, Russell King - ARM Linux wrote:
> On Mon, Sep 25, 2017 at 11:55:14AM +0200, Antoine Tenart wrote:
> > On Fri, Sep 22, 2017 at 12:07:31PM +0100, Russell King - ARM Linux wrote:
> > > On Thu, Sep 21, 2017 at 03:45:22PM +0200, Antoine Tenart wrote:
> > > > Convert the PPv2 driver to use phylink, which models the MAC to PHY
> > > > link. The phylink support is made such a way the GoP link IRQ can still
> > > > be used: the two modes are incompatible and the GoP link IRQ will be
> > > > used if no PHY is described in the device tree. This is the same
> > > > behaviour as before.
> > >
> > > This makes no sense. The point of phylink is to be able to support SFP
> > > cages, and SFP cages do not have a PHY described in DT. So, when you
> > > want to use phylink because of SFP, you can't, because if you omit
> > > the PHY the driver avoids using phylink.
> >
> > Yes that's an issue. However we do need to support the GoP link IRQ
> > which is also needed in some cases where there is no PHY (and when
> > phylink cannot be used). What would you propose to differentiate those
> > two cases: no PHY using phylink, and no PHY using the GoP link IRQ?
>
> Can you describe what the GoP link IRQ is doing please?
In cases where there is no PHY connected to the MAC and no SFP cage is
used. One example is when a SOHO switch is connected directly to a
serdes lane. In such cases we still need to have a minimal link
management. The GoP link interrupt helps doing so as it raises when the
serdes is in sync and AN succeeded.
I also wonder if this is needed when using passive cables?
Antoine
--
Antoine Ténart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* Re: [PATCH RESEND] wireless: iwlwifi: fix minor code style issues
From: Christoph Böhmwalder @ 2017-09-25 11:51 UTC (permalink / raw)
To: Coelho, Luciano, linux-kernel@vger.kernel.org, trivial@kernel.org,
Berg, Johannes, kvalo@codeaurora.org, netdev@vger.kernel.org,
linux-wireless@vger.kernel.org, Grumbach, Emmanuel
In-Reply-To: <1506340012.3276.17.camel@intel.com>
[-- Attachment #1.1: Type: text/plain, Size: 306 bytes --]
> Why are you already resending this?
Sorry, I guess I was too impatient. I also messed up the spelling in a
"To:" line and forgot trivial@kernel.org the first time I sent it, so I
figured I'd just fix it in a resend.
I'll make sure to wait a little longer next time.
--
Regards,
Christoph
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH RESEND] wireless: iwlwifi: fix minor code style issues
From: Coelho, Luciano @ 2017-09-25 11:47 UTC (permalink / raw)
To: linux-kernel@vger.kernel.org, trivial@kernel.org,
christoph@boehmwalder.at, Berg, Johannes, kvalo@codeaurora.org,
netdev@vger.kernel.org, linux-wireless@vger.kernel.org,
Grumbach, Emmanuel
In-Reply-To: <912deca9-79b6-7a44-6859-dbe532d90fed@boehmwalder.at>
On Mon, 2017-09-25 at 13:37 +0200, Christoph Böhmwalder wrote:
> Fixes three trivial issues as reported by checkpatch.pl, namely two
switch/case indentation issues and one alignment issue in a multiline
comment.
Signed-off-by: Christoph Böhmwalder <christoph@boehmwalder.at>
---
Why are you already resending this? You sent the first email 2 days ago,
you can't expect that a non-critical patch be merged in such a short
time (especially during the weekend).
--
Cheers,
Luca
^ permalink raw reply
* Re: [PATCH 5/5] xfrm: eradicate size_t
From: Steffen Klassert @ 2017-09-25 11:46 UTC (permalink / raw)
To: Alexey Dobriyan; +Cc: herbert, davem, netdev
In-Reply-To: <20170921204853.GF13550@avx2>
On Thu, Sep 21, 2017 at 11:48:54PM +0300, Alexey Dobriyan wrote:
> All netlink message sizes are a) unsigned, b) can't be >= 4GB in size
> because netlink doesn't support >= 64KB messages in the first place.
>
> All those size_t across the code are a scam especially across networking
> which likes to work with small numbers like 1500 or 65536.
>
> Propagate unsignedness and flip some "int" to "unsigned int" as well.
>
> This is preparation to switching nlmsg_new() to "unsigned int".
>
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
All applied to ipsec-next, thanks Alexey!
^ permalink raw reply
* [PATCH RESEND] wireless: iwlwifi: fix minor code style issues
From: Christoph Böhmwalder @ 2017-09-25 11:37 UTC (permalink / raw)
To: johannes.berg, emmanuel.grumbach, luciano.coelho, kvalo,
linux-wireless, netdev, linux-kernel, trivial
Cc: Christoph Böhmwalder
[-- Attachment #1.1: Type: text/plain, Size: 1716 bytes --]
Fixes three trivial issues as reported by checkpatch.pl, namely two
switch/case indentation issues and one alignment issue in a multiline
comment.
Signed-off-by: Christoph Böhmwalder <christoph@boehmwalder.at>
---
drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index 99676d6c4713..ccdb247d68c5 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -832,7 +832,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
capa->standard_phy_calibration_size =
le32_to_cpup((__le32 *)tlv_data);
break;
- case IWL_UCODE_TLV_SEC_RT:
+ case IWL_UCODE_TLV_SEC_RT:
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR,
tlv_len);
drv->fw.type = IWL_FW_MVM;
@@ -864,7 +864,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
FW_PHY_CFG_RX_CHAIN) >>
FW_PHY_CFG_RX_CHAIN_POS;
break;
- case IWL_UCODE_TLV_SECURE_SEC_RT:
+ case IWL_UCODE_TLV_SECURE_SEC_RT:
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR,
tlv_len);
drv->fw.type = IWL_FW_MVM;
@@ -1335,7 +1335,8 @@ static void iwl_req_fw_callback(const struct
firmware *ucode_raw, void *context)
/* Runtime instructions and 2 copies of data:
* 1) unmodified from disk
- * 2) backup cache for save/restore during power-downs */
+ * 2) backup cache for save/restore during power-downs
+ */
for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
if (iwl_alloc_ucode(drv, pieces, i))
goto out_free_fw;
--
2.13.5
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply related
* Re: [PATCH net v2] sctp: Fix a big endian bug in sctp_diag_dump()
From: Neil Horman @ 2017-09-25 11:23 UTC (permalink / raw)
To: Dan Carpenter
Cc: Vlad Yasevich, Xin Long, David S. Miller, linux-sctp, netdev,
kernel-janitors
In-Reply-To: <20170925101926.db4f6x4hblh7tcvo@mwanda>
On Mon, Sep 25, 2017 at 01:19:26PM +0300, Dan Carpenter wrote:
> The sctp_for_each_transport() function takes an pointer to int. The
> cb->args[] array holds longs so it's only using the high 32 bits. It
> works on little endian system but will break on big endian 64 bit
> machines.
>
> Fixes: d25adbeb0cdb ("sctp: fix an use-after-free issue in sctp_sock_dump")
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> ---
> v2: The v1 patch changed the function to take a long pointer, but v2
> just changes the caller.
>
> diff --git a/net/sctp/sctp_diag.c b/net/sctp/sctp_diag.c
> index 22ed01a76b19..a72a7d925d46 100644
> --- a/net/sctp/sctp_diag.c
> +++ b/net/sctp/sctp_diag.c
> @@ -463,6 +463,7 @@ static void sctp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
> .r = r,
> .net_admin = netlink_net_capable(cb->skb, CAP_NET_ADMIN),
> };
> + int pos = cb->args[2];
>
> /* eps hashtable dumps
> * args:
> @@ -493,7 +494,8 @@ static void sctp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
> goto done;
>
> sctp_for_each_transport(sctp_sock_filter, sctp_sock_dump,
> - net, (int *)&cb->args[2], &commp);
> + net, &pos, &commp);
> + cb->args[2] = pos;
>
> done:
> cb->args[1] = cb->args[4];
>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
^ 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