* [PATCH v3 net-next 5/7] udp: Add UDP flow dissection functions to IPv4 and IPv6
From: Tom Herbert @ 2016-10-18 17:02 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
In-Reply-To: <20161018170243.1369807-1-tom@herbertland.com>
Add per protocol offload callbacks for flow_dissect to UDP for
IPv4 and IPv6. The callback functions extract the port number
information and with the packet addresses (given in an argument with
type flow_dissector_key_addrs) it performs a lookup on the UDP
socket. If a socket is found and flow_dissect is set for the
socket then that function is called.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
net/ipv4/udp_offload.c | 39 +++++++++++++++++++++++++++++++++++++++
net/ipv6/udp_offload.c | 40 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 78 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index f9333c9..c7753ba 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -377,11 +377,50 @@ static int udp4_gro_complete(struct sk_buff *skb, int nhoff)
return udp_gro_complete(skb, nhoff, udp4_lib_lookup_skb);
}
+/* Assumes rcu lock is held */
+static int udp4_flow_dissect(const struct sk_buff *skb, void *data, int hlen,
+ int *nhoff, u8 *ip_proto, __be16 *proto,
+ struct flow_dissector_key_addrs *key_addrs)
+{
+ u16 _ports[2], *ports;
+ struct net *net;
+ struct sock *sk;
+ int dif = -1;
+
+ /* See if there is a flow dissector in the UDP socket */
+
+ if (skb->dev) {
+ net = dev_net(skb->dev);
+ dif = skb->dev->ifindex;
+ } else if (skb->sk) {
+ net = sock_net(skb->sk);
+ } else {
+ return FLOW_DIS_RET_PASS;
+ }
+
+ ports = __skb_header_pointer(skb, *nhoff, sizeof(_ports),
+ data, hlen, &_ports);
+ if (!ports)
+ return FLOW_DIS_RET_BAD;
+
+ sk = udp4_lib_lookup_noref(net,
+ key_addrs->v4addrs.src, ports[0],
+ key_addrs->v4addrs.dst, ports[1],
+ dif);
+
+ if (sk && udp_sk(sk)->flow_dissect)
+ return udp_sk(sk)->flow_dissect(sk, skb, data, hlen, nhoff,
+ ip_proto, proto);
+ else
+ return FLOW_DIS_RET_PASS;
+}
+
static const struct net_offload udpv4_offload = {
.callbacks = {
.gso_segment = udp4_ufo_fragment,
.gro_receive = udp4_gro_receive,
.gro_complete = udp4_gro_complete,
+ .flow_dissect = udp4_flow_dissect,
},
};
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
index ac858c4..12d9a92 100644
--- a/net/ipv6/udp_offload.c
+++ b/net/ipv6/udp_offload.c
@@ -1,5 +1,5 @@
/*
- * IPV6 GSO/GRO offload support
+ * ipv6 gso/gro offload support
* Linux INET6 implementation
*
* This program is free software; you can redistribute it and/or
@@ -163,11 +163,49 @@ static int udp6_gro_complete(struct sk_buff *skb, int nhoff)
return udp_gro_complete(skb, nhoff, udp6_lib_lookup_skb);
}
+/* Assumes rcu lock is held */
+static int udp6_flow_dissect(const struct sk_buff *skb, void *data, int hlen,
+ int *nhoff, u8 *ip_proto, __be16 *proto,
+ const struct flow_dissector_key_addrs *key_addrs)
+{
+ u16 _ports[2], *ports;
+ struct net *net;
+ struct sock *sk;
+ int dif = -1;
+
+ /* See if there is a flow dissector in the UDP socket */
+
+ if (skb->dev) {
+ net = dev_net(skb->dev);
+ dif = skb->dev->ifindex;
+ } else if (skb->sk) {
+ net = sock_net(skb->sk);
+ } else {
+ return FLOW_DIS_RET_PASS;
+ }
+
+ ports = __skb_header_pointer(skb, *nhoff, sizeof(_ports),
+ data, hlen, &_ports);
+ if (!ports)
+ return FLOW_DIS_RET_BAD;
+
+ sk = udp6_lib_lookup_noref(net,
+ &key_addrs->v6addrs.src, ports[0],
+ &key_addrs->v6addrs.dst, ports[1],
+ dif);
+
+ if (sk && udp_sk(sk)->flow_dissect)
+ return udp_sk(sk)->flow_dissect(sk, skb, data, hlen, nhoff,
+ ip_proto, proto);
+ return FLOW_DIS_RET_PASS;
+}
+
static const struct net_offload udpv6_offload = {
.callbacks = {
.gso_segment = udp6_ufo_fragment,
.gro_receive = udp6_gro_receive,
.gro_complete = udp6_gro_complete,
+ .flow_dissect = udp6_flow_dissect,
},
};
--
2.9.3
^ permalink raw reply related
* [PATCH v3 net-next 6/7] udp: UDP tunnel flow dissection infrastructure
From: Tom Herbert @ 2016-10-18 17:02 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
In-Reply-To: <20161018170243.1369807-1-tom@herbertland.com>
Add infrastructure to allow UDP tunnels to setup flow dissecion.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
include/net/udp_tunnel.h | 5 +++++
net/ipv4/udp_tunnel.c | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
index 02c5be0..81d2584 100644
--- a/include/net/udp_tunnel.h
+++ b/include/net/udp_tunnel.h
@@ -69,6 +69,10 @@ typedef struct sk_buff **(*udp_tunnel_gro_receive_t)(struct sock *sk,
struct sk_buff *skb);
typedef int (*udp_tunnel_gro_complete_t)(struct sock *sk, struct sk_buff *skb,
int nhoff);
+typedef int (*udp_tunnel_flow_dissect_t)(struct sock *sk,
+ const struct sk_buff *skb,
+ void *data, int hlen, int *nhoff,
+ u8 *ip_proto, __be16 *proto);
struct udp_tunnel_sock_cfg {
void *sk_user_data; /* user data used by encap_rcv call back */
@@ -78,6 +82,7 @@ struct udp_tunnel_sock_cfg {
udp_tunnel_encap_destroy_t encap_destroy;
udp_tunnel_gro_receive_t gro_receive;
udp_tunnel_gro_complete_t gro_complete;
+ udp_tunnel_flow_dissect_t flow_dissect;
};
/* Setup the given (UDP) sock to receive UDP encapsulated packets */
diff --git a/net/ipv4/udp_tunnel.c b/net/ipv4/udp_tunnel.c
index 58bd39f..4459288 100644
--- a/net/ipv4/udp_tunnel.c
+++ b/net/ipv4/udp_tunnel.c
@@ -72,6 +72,11 @@ void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
udp_sk(sk)->gro_receive = cfg->gro_receive;
udp_sk(sk)->gro_complete = cfg->gro_complete;
+ if (cfg->flow_dissect) {
+ udp_sk(sk)->flow_dissect = cfg->flow_dissect;
+ udp_flow_dissect_enable();
+ }
+
udp_tunnel_encap_enable(sock);
}
EXPORT_SYMBOL_GPL(setup_udp_tunnel_sock);
--
2.9.3
^ permalink raw reply related
* [PATCH v3 net-next 7/7] fou: Support flow dissection
From: Tom Herbert @ 2016-10-18 17:02 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
In-Reply-To: <20161018170243.1369807-1-tom@herbertland.com>
This patch performs flow dissection for GUE and FOU. This is an
optional feature on the receiver and is set by FOU_ATTR_DEEP_HASH
netlink configuration. When enable the UDP socket flow_dissect
function is set to fou_flow_dissect or gue_flow_dissect as
appropriate. These functions return FLOW_DIS_RET_IPPROTO and
set ip protocol argument. In the case of GUE the header is
parsed to find the protocol number.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
include/uapi/linux/fou.h | 1 +
net/ipv4/fou.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 68 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/fou.h b/include/uapi/linux/fou.h
index d2947c5..2c837eb 100644
--- a/include/uapi/linux/fou.h
+++ b/include/uapi/linux/fou.h
@@ -15,6 +15,7 @@ enum {
FOU_ATTR_IPPROTO, /* u8 */
FOU_ATTR_TYPE, /* u8 */
FOU_ATTR_REMCSUM_NOPARTIAL, /* flag */
+ FOU_ATTR_DEEP_HASH, /* flag */
__FOU_ATTR_MAX,
};
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
index cf50f7e..95ac5a8 100644
--- a/net/ipv4/fou.c
+++ b/net/ipv4/fou.c
@@ -27,7 +27,8 @@ struct fou {
struct rcu_head rcu;
};
-#define FOU_F_REMCSUM_NOPARTIAL BIT(0)
+#define FOU_F_REMCSUM_NOPARTIAL BIT(0)
+#define FOU_F_DEEP_HASH BIT(1)
struct fou_cfg {
u16 type;
@@ -281,6 +282,16 @@ static int fou_gro_complete(struct sock *sk, struct sk_buff *skb,
return err;
}
+static int fou_flow_dissect(struct sock *sk, const struct sk_buff *skb,
+ void *data, int hlen, int *nhoff, u8 *ip_proto,
+ __be16 *proto)
+{
+ *ip_proto = fou_from_sock(sk)->protocol;
+ *nhoff += sizeof(struct udphdr);
+
+ return FLOW_DIS_RET_IPPROTO;
+}
+
static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off,
struct guehdr *guehdr, void *data,
size_t hdrlen, struct gro_remcsum *grc,
@@ -498,6 +509,48 @@ static int gue_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff)
return err;
}
+static int gue_flow_dissect(struct sock *sk, const struct sk_buff *skb,
+ void *data, int hlen, int *nhoff, u8 *ip_proto,
+ __be16 *proto)
+{
+ struct guehdr _hdr, *hdr;
+
+ hdr = __skb_header_pointer(skb, *nhoff + sizeof(struct udphdr),
+ sizeof(_hdr), data, hlen, &_hdr);
+ if (!hdr)
+ return FLOW_DIS_RET_BAD;
+
+ switch (hdr->version) {
+ case 0: /* Full GUE header present */
+ if (hdr->control)
+ return FLOW_DIS_RET_PASS;
+
+ *nhoff += sizeof(struct udphdr) + sizeof(_hdr) +
+ (hdr->hlen << 2);
+ *ip_proto = hdr->proto_ctype;
+
+ return FLOW_DIS_RET_IPPROTO;
+ case 1:
+ /* Direct encasulation of IPv4 or IPv6 */
+
+ switch (((struct iphdr *)hdr)->version) {
+ case 4:
+ *nhoff += sizeof(struct udphdr);
+ *ip_proto = IPPROTO_IPIP;
+ return FLOW_DIS_RET_IPPROTO;
+ case 6:
+ *nhoff += sizeof(struct udphdr);
+ *ip_proto = IPPROTO_IPV6;
+ return FLOW_DIS_RET_IPPROTO;
+ default:
+ return FLOW_DIS_RET_PASS;
+ }
+
+ default:
+ return FLOW_DIS_RET_PASS;
+ }
+}
+
static int fou_add_to_port_list(struct net *net, struct fou *fou)
{
struct fou_net *fn = net_generic(net, fou_net_id);
@@ -568,12 +621,16 @@ static int fou_create(struct net *net, struct fou_cfg *cfg,
tunnel_cfg.encap_rcv = fou_udp_recv;
tunnel_cfg.gro_receive = fou_gro_receive;
tunnel_cfg.gro_complete = fou_gro_complete;
+ if (cfg->flags & FOU_F_DEEP_HASH)
+ tunnel_cfg.flow_dissect = fou_flow_dissect;
fou->protocol = cfg->protocol;
break;
case FOU_ENCAP_GUE:
tunnel_cfg.encap_rcv = gue_udp_recv;
tunnel_cfg.gro_receive = gue_gro_receive;
tunnel_cfg.gro_complete = gue_gro_complete;
+ if (cfg->flags & FOU_F_DEEP_HASH)
+ tunnel_cfg.flow_dissect = gue_flow_dissect;
break;
default:
err = -EINVAL;
@@ -637,6 +694,7 @@ static const struct nla_policy fou_nl_policy[FOU_ATTR_MAX + 1] = {
[FOU_ATTR_IPPROTO] = { .type = NLA_U8, },
[FOU_ATTR_TYPE] = { .type = NLA_U8, },
[FOU_ATTR_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG, },
+ [FOU_ATTR_DEEP_HASH] = { .type = NLA_FLAG },
};
static int parse_nl_config(struct genl_info *info,
@@ -677,6 +735,9 @@ static int parse_nl_config(struct genl_info *info,
if (info->attrs[FOU_ATTR_REMCSUM_NOPARTIAL])
cfg->flags |= FOU_F_REMCSUM_NOPARTIAL;
+ if (info->attrs[FOU_ATTR_DEEP_HASH])
+ cfg->flags |= FOU_F_DEEP_HASH;
+
return 0;
}
@@ -717,6 +778,11 @@ static int fou_fill_info(struct fou *fou, struct sk_buff *msg)
if (fou->flags & FOU_F_REMCSUM_NOPARTIAL)
if (nla_put_flag(msg, FOU_ATTR_REMCSUM_NOPARTIAL))
return -1;
+
+ if (fou->flags & FOU_F_DEEP_HASH)
+ if (nla_put_flag(msg, FOU_ATTR_DEEP_HASH))
+ return -1;
+
return 0;
}
--
2.9.3
^ permalink raw reply related
* [PATCH net-next] bnx2x: ethtool -x full support
From: Eric Dumazet @ 2016-10-18 17:08 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Ariel Elior
From: Eric Dumazet <edumazet@google.com>
Implement ethtool -x full support, so that rss key can be fetched
instead of assuming it matches /proc/sys/net/core/netdev_rss_key
content.
We might add "ethtool --rxfh" support later to set a different rss key.
Tested:
lpk51:~# ethtool --show-rxfh eth0
RX flow hash indirection table for eth0 with 4 RX ring(s):
0: 0 1 2 3 0 1 2 3
8: 0 1 2 3 0 1 2 3
16: 0 1 2 3 0 1 2 3
24: 0 1 2 3 0 1 2 3
32: 0 1 2 3 0 1 2 3
40: 0 1 2 3 0 1 2 3
48: 0 1 2 3 0 1 2 3
56: 0 1 2 3 0 1 2 3
64: 0 1 2 3 0 1 2 3
72: 0 1 2 3 0 1 2 3
80: 0 1 2 3 0 1 2 3
88: 0 1 2 3 0 1 2 3
96: 0 1 2 3 0 1 2 3
104: 0 1 2 3 0 1 2 3
112: 0 1 2 3 0 1 2 3
120: 0 1 2 3 0 1 2 3
RSS hash key:
8b:a9:3a:ff:3e:f8:44:bd:5a:44:b7:b5:6d:e8:2d:f0:f0:72:98:54:03:86:8f:39:a4:42:5a:b3:84:71:5c:4f:1c:18:d6:a3:04:68:85:ac
lpk51:~# cat /proc/sys/net/core/netdev_rss_key
8b:a9:3a:ff:3e:f8:44:bd:5a:44:b7:b5:6d:e8:2d:f0:f0:72:98:54:03:86:8f:39:a4:42:5a:b3:84:71:5c:4f:1c:18:d6:a3:04:68:85:ac:22:1f:50:76:d4:c8:a5:20:7b:61:3c:0c
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Ariel Elior <ariel.elior@qlogic.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 2
drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 47 ++++++----
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | 2
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h | 5 -
4 files changed, 35 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 0a9108cd4c45..b979bb7c4ffb 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -2106,7 +2106,7 @@ int bnx2x_rss(struct bnx2x *bp, struct bnx2x_rss_config_obj *rss_obj,
if (config_hash) {
/* RSS keys */
- netdev_rss_key_fill(params.rss_key, T_ETH_RSS_KEY * 4);
+ netdev_rss_key_fill(&rss_obj->rss_key, T_ETH_RSS_KEY * 4);
__set_bit(BNX2X_RSS_SET_SRCH, ¶ms.rss_flags);
}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index 85a7800bfc12..28bc9479fc74 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -3421,6 +3421,13 @@ static u32 bnx2x_get_rxfh_indir_size(struct net_device *dev)
return T_ETH_INDIRECTION_TABLE_SIZE;
}
+static u32 bnx2x_get_rxfh_key_size(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ return (bp->port.pmf || !CHIP_IS_E1x(bp)) ? T_ETH_RSS_KEY * 4 : 0;
+}
+
static int bnx2x_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
u8 *hfunc)
{
@@ -3430,23 +3437,30 @@ static int bnx2x_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
- if (!indir)
- return 0;
- /* Get the current configuration of the RSS indirection table */
- bnx2x_get_rss_ind_table(&bp->rss_conf_obj, ind_table);
-
- /*
- * We can't use a memcpy() as an internal storage of an
- * indirection table is a u8 array while indir->ring_index
- * points to an array of u32.
- *
- * Indirection table contains the FW Client IDs, so we need to
- * align the returned table to the Client ID of the leading RSS
- * queue.
- */
- for (i = 0; i < T_ETH_INDIRECTION_TABLE_SIZE; i++)
- indir[i] = ind_table[i] - bp->fp->cl_id;
+ if (key) {
+ if (bp->port.pmf || !CHIP_IS_E1x(bp))
+ memcpy(key, &bp->rss_conf_obj.rss_key, T_ETH_RSS_KEY * 4);
+ else
+ memset(key, 0, T_ETH_RSS_KEY * 4);
+ }
+
+ if (indir) {
+ /* Get the current configuration of the RSS indirection table */
+ bnx2x_get_rss_ind_table(&bp->rss_conf_obj, ind_table);
+
+ /*
+ * We can't use a memcpy() as an internal storage of an
+ * indirection table is a u8 array while indir->ring_index
+ * points to an array of u32.
+ *
+ * Indirection table contains the FW Client IDs, so we need to
+ * align the returned table to the Client ID of the leading RSS
+ * queue.
+ */
+ for (i = 0; i < T_ETH_INDIRECTION_TABLE_SIZE; i++)
+ indir[i] = ind_table[i] - bp->fp->cl_id;
+ }
return 0;
}
@@ -3628,6 +3642,7 @@ static const struct ethtool_ops bnx2x_ethtool_ops = {
.get_ethtool_stats = bnx2x_get_ethtool_stats,
.get_rxnfc = bnx2x_get_rxnfc,
.set_rxnfc = bnx2x_set_rxnfc,
+ .get_rxfh_key_size = bnx2x_get_rxfh_key_size,
.get_rxfh_indir_size = bnx2x_get_rxfh_indir_size,
.get_rxfh = bnx2x_get_rxfh,
.set_rxfh = bnx2x_set_rxfh,
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
index cea6bdcde33f..3b1becc23160 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
@@ -4538,7 +4538,7 @@ static int bnx2x_setup_rss(struct bnx2x *bp,
/* RSS keys */
if (test_bit(BNX2X_RSS_SET_SRCH, &p->rss_flags)) {
u8 *dst = (u8 *)(data->rss_key) + sizeof(data->rss_key);
- const u8 *src = (const u8 *)p->rss_key;
+ const u8 *src = (const u8 *)o->rss_key;
int i;
/* Apparently, bnx2x reads this array in reverse order
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
index 0bf2fd470819..0092991796d3 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
@@ -744,9 +744,6 @@ struct bnx2x_config_rss_params {
/* Indirection table */
u8 ind_table[T_ETH_INDIRECTION_TABLE_SIZE];
- /* RSS hash values */
- u32 rss_key[10];
-
/* valid only iff BNX2X_RSS_UPDATE_TOE is set */
u16 toe_rss_bitmap;
};
@@ -760,6 +757,8 @@ struct bnx2x_rss_config_obj {
/* Last configured indirection table */
u8 ind_table[T_ETH_INDIRECTION_TABLE_SIZE];
+ u32 rss_key[T_ETH_RSS_KEY];
+
/* flags for enabling 4-tupple hash on UDP */
u8 udp_rss_v4;
u8 udp_rss_v6;
^ permalink raw reply related
* Re: [PATCH -next] qed: Remove useless set memory to zero use memset()
From: Sergei Shtylyov @ 2016-10-18 17:20 UTC (permalink / raw)
To: Wei Yongjun, Yuval Mintz, Ariel Elior
Cc: Wei Yongjun, everest-linux-l2, netdev
In-Reply-To: <1476806090-4456-1-git-send-email-weiyj.lk@gmail.com>
On 10/18/2016 06:54 PM, Wei Yongjun wrote:
> From: Wei Yongjun <weiyongjun1@huawei.com>
>
> The memory return by kzalloc() has already be set to zero, so
Returned?
> remove useless memset(0).
>
> Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
[...]
MBR, Sergei
^ permalink raw reply
* Re: [PATCH net-next] ethernet/sfc: use core min/max MTU checking
From: Sergei Shtylyov @ 2016-10-18 17:21 UTC (permalink / raw)
To: Bert Kenward, Dave Miller
Cc: Solarflare Linux Maintainers, netdev, Jarod Wilson
In-Reply-To: <4705a2ea-7734-b549-561c-bc7b6d8710d3@solarflare.com>
On 10/18/2016 07:47 PM, Bert Kenward wrote:
> Fixes: 61e84623 ("net: centralize net_device min/max MTU checking")
The commit SHA1 should be at least 12 digits here.
> Signed-off-by: Bert Kenward <bkenward@solarflare.com>
[...]
MBR, Sergei
^ permalink raw reply
* [PATCH net-next] bpf: Detect identical PTR_TO_MAP_VALUE_OR_NULL registers
From: Thomas Graf @ 2016-10-18 17:51 UTC (permalink / raw)
To: davem; +Cc: netdev, alexei.starovoitov, daniel, jbacik
A BPF program is required to check the return register of a
map_elem_lookup() call before accessing memory. The verifier keeps
track of this by converting the type of the result register from
PTR_TO_MAP_VALUE_OR_NULL to PTR_TO_MAP_VALUE after a conditional
jump ensures safety. This check is currently exclusively performed
for the result register 0.
In the event the compiler reorders instructions, BPF_MOV64_REG
instructions may be moved before the conditional jump which causes
them to keep their type PTR_TO_MAP_VALUE_OR_NULL to which the
verifier objects when the register is accessed:
0: (b7) r1 = 10
1: (7b) *(u64 *)(r10 -8) = r1
2: (bf) r2 = r10
3: (07) r2 += -8
4: (18) r1 = 0x59c00000
6: (85) call 1
7: (bf) r4 = r0
8: (15) if r0 == 0x0 goto pc+1
R0=map_value(ks=8,vs=8) R4=map_value_or_null(ks=8,vs=8) R10=fp
9: (7a) *(u64 *)(r4 +0) = 0
R4 invalid mem access 'map_value_or_null'
This commit extends the verifier to keep track of all identical
PTR_TO_MAP_VALUE_OR_NULL registers after a map_elem_lookup() by
assigning them an ID and then marking them all when the conditional
jump is observed.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Reviewed-by: Josef Bacik <jbacik@fb.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
---
include/linux/bpf_verifier.h | 2 +-
kernel/bpf/verifier.c | 61 +++++++++++++++++-------
tools/testing/selftests/bpf/test_verifier.c | 72 +++++++++++++++++++++++++++++
3 files changed, 118 insertions(+), 17 deletions(-)
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 7035b99..ac5b393 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -23,13 +23,13 @@ struct bpf_reg_state {
* result in a bad access.
*/
u64 min_value, max_value;
+ u32 id;
union {
/* valid when type == CONST_IMM | PTR_TO_STACK | UNKNOWN_VALUE */
s64 imm;
/* valid when type == PTR_TO_PACKET* */
struct {
- u32 id;
u16 off;
u16 range;
};
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 99a7e5b..846d7ce 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -212,9 +212,10 @@ static void print_verifier_state(struct bpf_verifier_state *state)
else if (t == CONST_PTR_TO_MAP || t == PTR_TO_MAP_VALUE ||
t == PTR_TO_MAP_VALUE_OR_NULL ||
t == PTR_TO_MAP_VALUE_ADJ)
- verbose("(ks=%d,vs=%d)",
+ verbose("(ks=%d,vs=%d,id=%u)",
reg->map_ptr->key_size,
- reg->map_ptr->value_size);
+ reg->map_ptr->value_size,
+ reg->id);
if (reg->min_value != BPF_REGISTER_MIN_RANGE)
verbose(",min_value=%llu",
(unsigned long long)reg->min_value);
@@ -447,6 +448,7 @@ static void mark_reg_unknown_value(struct bpf_reg_state *regs, u32 regno)
{
BUG_ON(regno >= MAX_BPF_REG);
regs[regno].type = UNKNOWN_VALUE;
+ regs[regno].id = 0;
regs[regno].imm = 0;
}
@@ -1252,6 +1254,7 @@ static int check_call(struct bpf_verifier_env *env, int func_id)
return -EINVAL;
}
regs[BPF_REG_0].map_ptr = meta.map_ptr;
+ regs[BPF_REG_0].id = ++env->id_gen;
} else {
verbose("unknown return type %d of func %d\n",
fn->ret_type, func_id);
@@ -1644,8 +1647,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
insn->src_reg);
return -EACCES;
}
- regs[insn->dst_reg].type = UNKNOWN_VALUE;
- regs[insn->dst_reg].map_ptr = NULL;
+ mark_reg_unknown_value(regs, insn->dst_reg);
}
} else {
/* case: R = imm
@@ -1907,6 +1909,38 @@ static void reg_set_min_max_inv(struct bpf_reg_state *true_reg,
check_reg_overflow(true_reg);
}
+static void mark_map_reg(struct bpf_reg_state *regs, u32 regno, u32 id,
+ enum bpf_reg_type type)
+{
+ struct bpf_reg_state *reg = ®s[regno];
+
+ if (reg->type == PTR_TO_MAP_VALUE_OR_NULL && reg->id == id) {
+ reg->type = type;
+ if (type == UNKNOWN_VALUE)
+ mark_reg_unknown_value(regs, regno);
+ }
+}
+
+/* The logic is similar to find_good_pkt_pointers(), both could eventually
+ * be folded together at some point.
+ */
+static void mark_map_regs(struct bpf_verifier_state *state, u32 regno,
+ enum bpf_reg_type type)
+{
+ struct bpf_reg_state *regs = state->regs;
+ int i;
+
+ for (i = 0; i < MAX_BPF_REG; i++)
+ mark_map_reg(regs, i, regs[regno].id, type);
+
+ for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) {
+ if (state->stack_slot_type[i] != STACK_SPILL)
+ continue;
+ mark_map_reg(state->spilled_regs, i / BPF_REG_SIZE,
+ regs[regno].id, type);
+ }
+}
+
static int check_cond_jmp_op(struct bpf_verifier_env *env,
struct bpf_insn *insn, int *insn_idx)
{
@@ -1994,18 +2028,13 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
if (BPF_SRC(insn->code) == BPF_K &&
insn->imm == 0 && (opcode == BPF_JEQ || opcode == BPF_JNE) &&
dst_reg->type == PTR_TO_MAP_VALUE_OR_NULL) {
- if (opcode == BPF_JEQ) {
- /* next fallthrough insn can access memory via
- * this register
- */
- regs[insn->dst_reg].type = PTR_TO_MAP_VALUE;
- /* branch targer cannot access it, since reg == 0 */
- mark_reg_unknown_value(other_branch->regs,
- insn->dst_reg);
- } else {
- other_branch->regs[insn->dst_reg].type = PTR_TO_MAP_VALUE;
- mark_reg_unknown_value(regs, insn->dst_reg);
- }
+ /* Mark all identical map registers in each branch as either
+ * safe or unknown depending R == 0 or R != 0 conditional.
+ */
+ mark_map_regs(this_branch, insn->dst_reg,
+ opcode == BPF_JEQ ? PTR_TO_MAP_VALUE : UNKNOWN_VALUE);
+ mark_map_regs(other_branch, insn->dst_reg,
+ opcode == BPF_JEQ ? UNKNOWN_VALUE : PTR_TO_MAP_VALUE);
} else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JGT &&
dst_reg->type == PTR_TO_PACKET &&
regs[insn->src_reg].type == PTR_TO_PACKET_END) {
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
index ff5df12..0ef8eaf 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -2588,6 +2588,78 @@ static struct bpf_test tests[] = {
.result_unpriv = REJECT,
.result = REJECT,
},
+ {
+ "multiple registers share map_lookup_elem result",
+ .insns = {
+ BPF_MOV64_IMM(BPF_REG_1, 10),
+ BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
+ BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map1 = { 4 },
+ .result = ACCEPT,
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS
+ },
+ {
+ "invalid memory access with multiple map_lookup_elem calls",
+ .insns = {
+ BPF_MOV64_IMM(BPF_REG_1, 10),
+ BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
+ BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
+ BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map1 = { 4 },
+ .result = REJECT,
+ .errstr = "R4 !read_ok",
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS
+ },
+ {
+ "valid indirect map_lookup_elem access with 2nd lookup in branch",
+ .insns = {
+ BPF_MOV64_IMM(BPF_REG_1, 10),
+ BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
+ BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_MOV64_IMM(BPF_REG_2, 10),
+ BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 3),
+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
+ BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map1 = { 4 },
+ .result = ACCEPT,
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS
+ },
};
static int probe_filter_length(const struct bpf_insn *fp)
--
2.7.4
^ permalink raw reply related
* Re: [PATCH net v2] bridge: multicast: restore perm router ports on multicast enable
From: David Miller @ 2016-10-18 17:53 UTC (permalink / raw)
To: nikolay; +Cc: netdev, sashok, roopa, herbert, stephen
In-Reply-To: <1476806988-20557-1-git-send-email-nikolay@cumulusnetworks.com>
From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Date: Tue, 18 Oct 2016 18:09:48 +0200
> Satish reported a problem with the perm multicast router ports not getting
> reenabled after some series of events, in particular if it happens that the
> multicast snooping has been disabled and the port goes to disabled state
> then it will be deleted from the router port list, but if it moves into
> non-disabled state it will not be re-added because the mcast snooping is
> still disabled, and enabling snooping later does nothing.
>
> Here are the steps to reproduce, setup br0 with snooping enabled and eth1
> added as a perm router (multicast_router = 2):
> 1. $ echo 0 > /sys/class/net/br0/bridge/multicast_snooping
> 2. $ ip l set eth1 down
> ^ This step deletes the interface from the router list
> 3. $ ip l set eth1 up
> ^ This step does not add it again because mcast snooping is disabled
> 4. $ echo 1 > /sys/class/net/br0/bridge/multicast_snooping
> 5. $ bridge -d -s mdb show
> <empty>
>
> At this point we have mcast enabled and eth1 as a perm router (value = 2)
> but it is not in the router list which is incorrect.
>
> After this change:
> 1. $ echo 0 > /sys/class/net/br0/bridge/multicast_snooping
> 2. $ ip l set eth1 down
> ^ This step deletes the interface from the router list
> 3. $ ip l set eth1 up
> ^ This step does not add it again because mcast snooping is disabled
> 4. $ echo 1 > /sys/class/net/br0/bridge/multicast_snooping
> 5. $ bridge -d -s mdb show
> router ports on br0: eth1
>
> Note: we can directly do br_multicast_enable_port for all because the
> querier timer already has checks for the port state and will simply
> expire if it's in blocking/disabled. See the comment added by
> commit 9aa66382163e7 ("bridge: multicast: add a comment to
> br_port_state_selection about blocking state")
>
> Fixes: 561f1103a2b7 ("bridge: Add multicast_snooping sysfs toggle")
> Reported-by: Satish Ashok <sashok@cumulusnetworks.com>
> Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Applied and queued up for -stable, thanks!
^ permalink raw reply
* Re: [PATCH net-next] ethernet/sfc: use core min/max MTU checking
From: David Miller @ 2016-10-18 17:54 UTC (permalink / raw)
To: bkenward; +Cc: linux-net-drivers, netdev, jarod
In-Reply-To: <4705a2ea-7734-b549-561c-bc7b6d8710d3@solarflare.com>
From: Bert Kenward <bkenward@solarflare.com>
Date: Tue, 18 Oct 2016 17:47:45 +0100
> Fixes: 61e84623 ("net: centralize net_device min/max MTU checking")
> Signed-off-by: Bert Kenward <bkenward@solarflare.com>
Applied with Fixes tag fixed up to use a 12 character SHA1-ID.
^ permalink raw reply
* Re: [PATCH v3 net-next 0/7] udp: Flow dissection for tunnels
From: David Miller @ 2016-10-18 18:03 UTC (permalink / raw)
To: tom; +Cc: netdev, kernel-team
In-Reply-To: <20161018170243.1369807-1-tom@herbertland.com>
From: Tom Herbert <tom@herbertland.com>
Date: Tue, 18 Oct 2016 10:02:36 -0700
> v3:
> - Fix build issues with modules that call IPv6 functions and
> CONFIG_INET is not set.
> - Fix compilation error in init'ing .flow_dissect in IPv6 UDP
> offload.
Still doesn't build:
net/ipv6/udp_offload.c:208:19: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
.flow_dissect = udp6_flow_dissect,
^
net/ipv6/udp_offload.c:208:19: note: (near initialization for ‘udpv6_offload.callbacks.flow_dissect’)
cc1: some warnings being treated as errors
scripts/Makefile.build:289: recipe for target 'net/ipv6/udp_offload.o' failed
make[2]: *** [net/ipv6/udp_offload.o] Error 1
make[2]: *** Waiting for unfinished jobs....
scripts/Makefile.build:440: recipe for target 'net/ipv6' failed
make[1]: *** [net/ipv6] Error 2
make[1]: *** Waiting for unfinished jobs....
Makefile:969: recipe for target 'net' failed
make: *** [net] Error 2
make: *** Waiting for unfinished jobs....
The final argument to udp6_flow_dissect() is marked const but that is not what the
method definition wants.
^ permalink raw reply
* Re: [PATCH v3 0/4] support smc91x on mainstone and devicetree
From: David Miller @ 2016-10-18 18:14 UTC (permalink / raw)
To: robert.jarzmik
Cc: robh+dt, mark.rutland, daniel, haojian.zhuang, jic23, dhowells,
nico, netdev, devicetree, linux-kernel, linux-arm-kernel,
linux-am33-list
In-Reply-To: <1476733532-29716-1-git-send-email-robert.jarzmik@free.fr>
From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: Mon, 17 Oct 2016 21:45:28 +0200
> This serie aims at bringing support to mainstone board on a device-tree based
> build, as what is already in place for legacy mainstone.
>
> The bulk of the mainstone "specific" behavior is that a u16 write doesn't work
> on a address of the form 4*n + 2, while it works on 4*n.
>
> The legacy workaround was in SMC_outw(), with calls to
> machine_is_mainstone(). These calls don't work with a pxa27x-dt machine type,
> which is used when a generic device-tree pxa27x machine is used to boot the
> mainstone board.
>
> Therefore, this serie enables the smc91c111 adapter of the mainstone board to
> work on a device-tree build, exaclty as it's been working for years with the
> legacy arch/arm/mach-pxa/mainstone.c definition.
>
> As a sum up, this extends an existing mechanism to device-tree based pxa platforms.
Series applied, thanks.
^ permalink raw reply
* Re: [PATCH 1/3 net v2] ibmvnic: Driver Version 1.0.1
From: David Miller @ 2016-10-18 18:17 UTC (permalink / raw)
To: tlfalcon; +Cc: netdev
In-Reply-To: <1476737789-17127-1-git-send-email-tlfalcon@linux.vnet.ibm.com>
From: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
Date: Mon, 17 Oct 2016 15:56:29 -0500
> Increment driver version to reflect features that have
> been added since release.
>
> Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
Applied.
^ permalink raw reply
* Re: [PATCH 2/3 net] ibmvnic: Fix GFP_KERNEL allocation in interrupt context
From: David Miller @ 2016-10-18 18:17 UTC (permalink / raw)
To: tlfalcon; +Cc: netdev
In-Reply-To: <1476736090-13588-2-git-send-email-tlfalcon@linux.vnet.ibm.com>
From: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
Date: Mon, 17 Oct 2016 15:28:09 -0500
> Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
Applied.
^ permalink raw reply
* Re: [PATCH 3/3 net] ibmvnic: Update MTU after device initialization
From: David Miller @ 2016-10-18 18:17 UTC (permalink / raw)
To: tlfalcon; +Cc: netdev
In-Reply-To: <1476736090-13588-3-git-send-email-tlfalcon@linux.vnet.ibm.com>
From: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
Date: Mon, 17 Oct 2016 15:28:10 -0500
> It is possible for the MTU to be changed during the initialization
> process with the VNIC Server. Ensure that the net device is updated
> to reflect the new MTU.
>
> Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
Applied.
^ permalink raw reply
* Re: [PATCH net] soreuseport: do not export reuseport_add_sock()
From: David Miller @ 2016-10-18 18:18 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
In-Reply-To: <1476739368.5650.60.camel@edumazet-glaptop3.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Mon, 17 Oct 2016 14:22:48 -0700
> From: Eric Dumazet <edumazet@google.com>
>
> reuseport_add_sock() is not used from a module,
> no need to export it.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied, thanks Eric.
^ permalink raw reply
* Re: [PATCH 20/28] net: bcm63xx: avoid referencing uninitialized variable
From: David Miller @ 2016-10-18 18:21 UTC (permalink / raw)
To: arnd
Cc: torvalds, linux-kernel, tremyfr, f.fainelli,
bcm-kernel-feedback-list, andrew, netdev, linux-arm-kernel
In-Reply-To: <20161017221650.1902729-1-arnd@arndb.de>
From: Arnd Bergmann <arnd@arndb.de>
Date: Tue, 18 Oct 2016 00:16:08 +0200
> gcc found a reference to an uninitialized variable in the error handling
> of bcm_enet_open, introduced by a recent cleanup:
>
> drivers/net/ethernet/broadcom/bcm63xx_enet.c: In function 'bcm_enet_open'
> drivers/net/ethernet/broadcom/bcm63xx_enet.c:1129:2: warning: 'phydev' may be used uninitialized in this function [-Wmaybe-uninitialized]
>
> This makes the use of that variable conditional, so we only reference it
> here after it has been used before. Unlike my normal patches, I have not
> build-tested this one, as I don't currently have mips test in my
> randconfig setup.
>
> Fixes: 625eb8667d6f ("net: ethernet: broadcom: bcm63xx: use phydev from struct net_device")
> Cc: Philippe Reynes <tremyfr@gmail.com>
> Reported-by: kbuild test robot <fengguang.wu@intel.com>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Applied.
^ permalink raw reply
* Re: [PATCH 21/28] net/hyperv: avoid uninitialized variable
From: David Miller @ 2016-10-18 18:21 UTC (permalink / raw)
To: arnd
Cc: kys, haiyangz, torvalds, linux-kernel, vkuznets, stephen, sixiao,
devel, netdev
In-Reply-To: <20161017221650.1902729-2-arnd@arndb.de>
From: Arnd Bergmann <arnd@arndb.de>
Date: Tue, 18 Oct 2016 00:16:09 +0200
> The hdr_offset variable is only if we deal with a TCP or UDP packet,
> but as the check surrounding its usage tests for skb_is_gso()
> instead, the compiler has no idea if the variable is initialized
> or not at that point:
>
> drivers/net/hyperv/netvsc_drv.c: In function ‘netvsc_start_xmit’:
> drivers/net/hyperv/netvsc_drv.c:494:42: error: ‘hdr_offset’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
>
> This adds an additional check for the transport type, which
> tells the compiler that this path cannot happen. Since the
> get_net_transport_info() function should always be inlined
> here, I don't expect this to result in additional runtime
> checks.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Applied.
^ permalink raw reply
* Re: [PATCH 27/28] rocker: fix maybe-uninitialized warning
From: David Miller @ 2016-10-18 18:21 UTC (permalink / raw)
To: arnd; +Cc: jiri, torvalds, linux-kernel, idosch, dan.carpenter, netdev
In-Reply-To: <20161017221650.1902729-8-arnd@arndb.de>
From: Arnd Bergmann <arnd@arndb.de>
Date: Tue, 18 Oct 2016 00:16:15 +0200
> In some rare configurations, we get a warning about the 'index' variable
> being used without an initialization:
>
> drivers/net/ethernet/rocker/rocker_ofdpa.c: In function ‘ofdpa_port_fib_ipv4.isra.16.constprop’:
> drivers/net/ethernet/rocker/rocker_ofdpa.c:2425:92: warning: ‘index’ may be used uninitialized in this function [-Wmaybe-uninitialized]
>
> This is a false positive, the logic is just a bit too complex for gcc
> to follow here. Moving the intialization of 'index' a little further
> down makes it clear to gcc that the function always returns an error
> if it is not initialized.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Applied.
^ permalink raw reply
* Re: [PATCH 1/1] net: vlan: Use sizeof instead of literal number
From: David Miller @ 2016-10-18 18:23 UTC (permalink / raw)
To: fgao; +Cc: kaber, netdev, gfree.wind
In-Reply-To: <1476751442-12112-1-git-send-email-fgao@ikuai8.com>
From: fgao@ikuai8.com
Date: Tue, 18 Oct 2016 08:44:02 +0800
> From: Gao Feng <fgao@ikuai8.com>
>
> Use sizeof variable instead of literal number to enhance the readability.
>
> Signed-off-by: Gao Feng <fgao@ikuai8.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next] r8152: add new products of Lenovo
From: David Miller @ 2016-10-18 18:24 UTC (permalink / raw)
To: hayeswang-Rasf1IRRPZFBDgjK7y7TUQ
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, oliver-GvhC2dPhHPQdnm+yROfE0A,
nic_swsd-Rasf1IRRPZFBDgjK7y7TUQ,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-usb-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1394712342-15778-225-Taiwan-albertk-Rasf1IRRPZFBDgjK7y7TUQ@public.gmane.org>
From: Hayes Wang <hayeswang-Rasf1IRRPZFBDgjK7y7TUQ@public.gmane.org>
Date: Tue, 18 Oct 2016 11:41:48 +0800
> Add the following four products of Lenovo and sort the order of the list.
>
> VID PID
> 0x17ef 0x3062
> 0x17ef 0x3069
> 0x17ef 0x720c
> 0x17ef 0x7214
>
> Signed-off-by: Hayes Wang <hayeswang-Rasf1IRRPZFBDgjK7y7TUQ@public.gmane.org>
Applied.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] ipv6: fix signedness of tmp_prefered_lft underflow check
From: David Miller @ 2016-10-18 18:25 UTC (permalink / raw)
To: jbohac; +Cc: julia.lawall, kuznet, jmorris, yoshfuji, kaber, netdev,
kbuild-all
In-Reply-To: <20161018150154.4tpivtvxygp7kjpd@dwarf.suse.cz>
From: Jiri Bohac <jbohac@suse.cz>
Date: Tue, 18 Oct 2016 17:01:54 +0200
> Commit 76506a986dc31394fd1f2741db037d29c7e57843 (IPv6: fix
> DESYNC_FACTOR) introduced a buggy check for underflow of
> tmp_prefered_lft. tmp_prefered_lft is unsigned, so the condition
> is always false.
>
> Signed-off-by: Jiri Bohac <jbohac@suse.cz>
> Reported-by: Julia Lawall <julia.lawall@lip6.fr>
> Fixes: 76506a986dc3 ("IPv6: fix DESYNC_FACTOR")
Does the check make any sense at all? I'd say just remove it.
^ permalink raw reply
* Re: [PATCH v3 net-next 3/8] net: qualcomm: move qcaspi_tx_cmd to qca_spi.c
From: David Miller @ 2016-10-18 18:28 UTC (permalink / raw)
To: stefan.wahren; +Cc: gregkh, jslaby, netdev, linux-kernel
In-Reply-To: <1476790054-27174-4-git-send-email-stefan.wahren@i2se.com>
From: Stefan Wahren <stefan.wahren@i2se.com>
Date: Tue, 18 Oct 2016 13:27:29 +0200
> diff --git a/drivers/net/ethernet/qualcomm/qca_7k.h b/drivers/net/ethernet/qualcomm/qca_7k.h
> index 1cad851..b390b1f 100644
> --- a/drivers/net/ethernet/qualcomm/qca_7k.h
> +++ b/drivers/net/ethernet/qualcomm/qca_7k.h
> @@ -67,6 +67,5 @@
> void qcaspi_spi_error(struct qcaspi *qca);
> int qcaspi_read_register(struct qcaspi *qca, u16 reg, u16 *result);
> int qcaspi_write_register(struct qcaspi *qca, u16 reg, u16 value);
> -int qcaspi_tx_cmd(struct qcaspi *qca, u16 cmd);
>
> #endif /* _QCA_7K_H */
> diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c
> index 6e2add9..5bcac62 100644
> --- a/drivers/net/ethernet/qualcomm/qca_spi.c
> +++ b/drivers/net/ethernet/qualcomm/qca_spi.c
> @@ -192,6 +192,30 @@ qcaspi_read_legacy(struct qcaspi *qca, u8 *dst, u32 len)
> return len;
> }
>
> +int
> +qcaspi_tx_cmd(struct qcaspi *qca, u16 cmd)
> +{
If you do this then you must mark this function 'static'.
^ permalink raw reply
* Re: [PATCH v3 net-next 5/8] net: qualcomm: move MTU handling to qca_common
From: David Miller @ 2016-10-18 18:29 UTC (permalink / raw)
To: stefan.wahren; +Cc: gregkh, jslaby, netdev, linux-kernel
In-Reply-To: <1476790054-27174-6-git-send-email-stefan.wahren@i2se.com>
From: Stefan Wahren <stefan.wahren@i2se.com>
Date: Tue, 18 Oct 2016 13:27:31 +0200
> The MTU of the QCA7000 is independent from it's host interface (UART,SPI).
> So move the change_mtu function to qca_common.
>
> Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
> ---
> drivers/net/ethernet/qualcomm/qca_common.c | 11 +++++++++++
> drivers/net/ethernet/qualcomm/qca_common.h | 3 +++
> drivers/net/ethernet/qualcomm/qca_spi.c | 13 +------------
> 3 files changed, 15 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/net/ethernet/qualcomm/qca_common.c b/drivers/net/ethernet/qualcomm/qca_common.c
> index 26453a9..9020c57 100644
> --- a/drivers/net/ethernet/qualcomm/qca_common.c
> +++ b/drivers/net/ethernet/qualcomm/qca_common.c
> @@ -154,3 +154,14 @@ qcafrm_fsm_decode(struct qcafrm_handle *handle, u8 *buf, u16 buf_len, u8 recv_by
>
> return ret;
> }
> +
> +int
> +qcacmn_netdev_change_mtu(struct net_device *dev, int new_mtu)
> +{
> + if ((new_mtu < QCAFRM_ETHMINMTU) || (new_mtu > QCAFRM_ETHMAXMTU))
> + return -EINVAL;
In net-next this limiting is implemented by the driver properly setting
netdev->min_mtu and netdev->max_mtu respectively.
And once you do that, you no longer need this method at all.
^ permalink raw reply
* Re: [PATCH v3 net-next 8/8] net: qualcomm: add QCA7000 UART driver
From: David Miller @ 2016-10-18 18:30 UTC (permalink / raw)
To: stefan.wahren; +Cc: gregkh, jslaby, netdev, linux-kernel
In-Reply-To: <1476790054-27174-9-git-send-email-stefan.wahren@i2se.com>
From: Stefan Wahren <stefan.wahren@i2se.com>
Date: Tue, 18 Oct 2016 13:27:34 +0200
> +void
> +qca_tty_receive(struct tty_struct *tty, const unsigned char *cp, char *fp,
> + int count)
> +{
> + struct qcauart *qca = tty->disc_data;
> + struct net_device_stats *n_stats = &qca->net_dev->stats;
> + int dropped = 0;
Please order local variable declarations from longest to shortest line.
> +netdev_tx_t
> +qcauart_netdev_xmit(struct sk_buff *skb, struct net_device *dev)
> +{
> + struct qcauart *qca = netdev_priv(dev);
> + struct net_device_stats *n_stats = &dev->stats;
> + u8 *pos;
> + u8 pad_len = 0;
> + int written;
Likewise.
^ permalink raw reply
* Re: iproute: ss truncates abstract unix domain socket embedding null
From: Isaac Boukris @ 2016-10-18 18:46 UTC (permalink / raw)
To: netdev
In-Reply-To: <CAC-fF8SMUsj8pPJO+VYdRSQAOcwyBpJY1C9V3VEk3zrFS=Jy4Q@mail.gmail.com>
Hi again,
On Sun, Oct 16, 2016 at 11:43 PM, Isaac Boukris <iboukris@gmail.com> wrote:
> Hello,
>
> The unix(7) man page says that null have no special meaning in
> abstract unix domain socket address (the length is specified
> therefore).
>
> However, when such name (embedding null) is used, ss (and netstat)
> will only show up to the first null occurrence (second technically, if
> we count the null prefix).
> e.g. the name "\0/tmp/fo\0.sock" is displayed as: "@/tmp/fo" (whilst
> strace tool shows it as: sun_path=@"/tmp/fo\0.sock").
>
> Would it be more useful if it printed the whole name and escaped the null?
> If so, would '\0' be ok for escaping the null?
Meanwhile, I've got it to escape the null character with with '\0' as suggested.
Can anyone take a look and advise if I'm on the right track? Thanks!
diff --git a/misc/ss.c b/misc/ss.c
index dd77b81..3e41f44 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -2869,7 +2869,7 @@ static int unix_show_sock(const struct
sockaddr_nl *addr, struct nlmsghdr *nlh,
struct filter *f = (struct filter *)arg;
struct unix_diag_msg *r = NLMSG_DATA(nlh);
struct rtattr *tb[UNIX_DIAG_MAX+1];
- char name[128];
+ char name[128*2];
struct sockstat stat = { .name = "*", .peer_name = "*" };
parse_rtattr(tb, UNIX_DIAG_MAX, (struct rtattr *)(r+1),
@@ -2891,11 +2891,25 @@ static int unix_show_sock(const struct
sockaddr_nl *addr, struct nlmsghdr *nlh,
}
if (tb[UNIX_DIAG_NAME]) {
int len = RTA_PAYLOAD(tb[UNIX_DIAG_NAME]);
+ char *real_name = RTA_DATA(tb[UNIX_DIAG_NAME]);
- memcpy(name, RTA_DATA(tb[UNIX_DIAG_NAME]), len);
- name[len] = '\0';
- if (name[0] == '\0')
+ if (real_name[0] == '\0') {
+ int i, j;
name[0] = '@';
+ for (i = j = 1; i < len; ++i) {
+ if (real_name[i] == '\0') {
+ name[j++] = '\\';
+ name[j++] = '0';
+ }
+ else
+ name[j++] = real_name[i];
+ }
+ name[j] = '\0';
+ } else {
+ memcpy(name, real_name, len);
+ name[len] = '\0';
+ }
+
stat.name = &name[0];
memcpy(stat.local.data, &stat.name, sizeof(stat.name));
}
^ 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