* [PATCH v2 next-next 07/12] fou: Add encap ops for IPv6 tunnels
From: Tom Herbert @ 2016-05-06 20:04 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
In-Reply-To: <1462565096-4076043-1-git-send-email-tom@herbertland.com>
Thsi packet adds IP tunnel encapsulation operations for IPv6. This
includes the infrastructure to add and delete operations. IPv6 variants
for fou6_build_header and gue6_build_header are added in a new
fou6 module. These encapsulation operations for fou and gue are
automatically added when the fou6 module loads.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
include/net/fou.h | 2 +-
include/net/ip6_tunnel.h | 14 +++++
net/ipv6/Makefile | 4 +-
net/ipv6/fou6.c | 140 +++++++++++++++++++++++++++++++++++++++++++++
net/ipv6/ip6_tunnel_core.c | 44 ++++++++++++++
5 files changed, 202 insertions(+), 2 deletions(-)
create mode 100644 net/ipv6/fou6.c
create mode 100644 net/ipv6/ip6_tunnel_core.c
diff --git a/include/net/fou.h b/include/net/fou.h
index 7d2fda2..f5cc691 100644
--- a/include/net/fou.h
+++ b/include/net/fou.h
@@ -9,7 +9,7 @@
#include <net/udp.h>
size_t fou_encap_hlen(struct ip_tunnel_encap *e);
-static size_t gue_encap_hlen(struct ip_tunnel_encap *e);
+size_t gue_encap_hlen(struct ip_tunnel_encap *e);
int __fou_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
u8 *protocol, __be16 *sport, int type);
diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h
index fb9e015..1c14c27 100644
--- a/include/net/ip6_tunnel.h
+++ b/include/net/ip6_tunnel.h
@@ -34,6 +34,20 @@ struct __ip6_tnl_parm {
__be32 o_key;
};
+struct ip6_tnl_encap_ops {
+ size_t (*encap_hlen)(struct ip_tunnel_encap *e);
+ int (*build_header)(struct sk_buff *skb, struct ip_tunnel_encap *e,
+ u8 *protocol, struct flowi6 *fl6);
+};
+
+extern const struct ip6_tnl_encap_ops __rcu *
+ ip6tun_encaps[MAX_IPTUN_ENCAP_OPS];
+
+int ip6_tnl_encap_add_ops(const struct ip6_tnl_encap_ops *op,
+ unsigned int num);
+int ip6_tnl_encap_del_ops(const struct ip6_tnl_encap_ops *op,
+ unsigned int num);
+
/* IPv6 tunnel */
struct ip6_tnl {
struct ip6_tnl __rcu *next; /* next tunnel in list */
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index 5e9d6bf..5cf4a1f 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -9,7 +9,7 @@ ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \
route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o udplite.o \
raw.o icmp.o mcast.o reassembly.o tcp_ipv6.o ping.o \
exthdrs.o datagram.o ip6_flowlabel.o inet6_connection_sock.o \
- udp_offload.o
+ udp_offload.o ip6_tunnel_core.o
ipv6-offload := ip6_offload.o tcpv6_offload.o exthdrs_offload.o
@@ -43,6 +43,8 @@ obj-$(CONFIG_IPV6_SIT) += sit.o
obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o
obj-$(CONFIG_IPV6_GRE) += ip6_gre.o
+obj-$(CONFIG_NET_FOU) += fou6.o
+
obj-y += addrconf_core.o exthdrs_core.o ip6_checksum.o ip6_icmp.o
obj-$(CONFIG_INET) += output_core.o protocol.o $(ipv6-offload)
diff --git a/net/ipv6/fou6.c b/net/ipv6/fou6.c
new file mode 100644
index 0000000..c972d0b
--- /dev/null
+++ b/net/ipv6/fou6.c
@@ -0,0 +1,140 @@
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/socket.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <net/fou.h>
+#include <net/ip.h>
+#include <net/ip6_tunnel.h>
+#include <net/ip6_checksum.h>
+#include <net/protocol.h>
+#include <net/udp.h>
+#include <net/udp_tunnel.h>
+
+static void fou6_build_udp(struct sk_buff *skb, struct ip_tunnel_encap *e,
+ struct flowi6 *fl6, u8 *protocol, __be16 sport)
+{
+ struct udphdr *uh;
+
+ skb_push(skb, sizeof(struct udphdr));
+ skb_reset_transport_header(skb);
+
+ uh = udp_hdr(skb);
+
+ uh->dest = e->dport;
+ uh->source = sport;
+ uh->len = htons(skb->len);
+ udp6_set_csum(!(e->flags & TUNNEL_ENCAP_FLAG_CSUM6), skb,
+ &fl6->saddr, &fl6->daddr, skb->len);
+
+ *protocol = IPPROTO_UDP;
+}
+
+int fou6_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
+ u8 *protocol, struct flowi6 *fl6)
+{
+ __be16 sport;
+ int err;
+ int type = e->flags & TUNNEL_ENCAP_FLAG_CSUM6 ?
+ SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
+
+ err = __fou_build_header(skb, e, protocol, &sport, type);
+ if (err)
+ return err;
+
+ fou6_build_udp(skb, e, fl6, protocol, sport);
+
+ return 0;
+}
+EXPORT_SYMBOL(fou6_build_header);
+
+int gue6_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
+ u8 *protocol, struct flowi6 *fl6)
+{
+ __be16 sport;
+ int err;
+ int type = e->flags & TUNNEL_ENCAP_FLAG_CSUM6 ?
+ SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
+
+ err = __gue_build_header(skb, e, protocol, &sport, type);
+ if (err)
+ return err;
+
+ fou6_build_udp(skb, e, fl6, protocol, sport);
+
+ return 0;
+}
+EXPORT_SYMBOL(gue6_build_header);
+
+#ifdef CONFIG_NET_FOU_IP_TUNNELS
+
+static const struct ip6_tnl_encap_ops fou_ip6tun_ops = {
+ .encap_hlen = fou_encap_hlen,
+ .build_header = fou6_build_header,
+};
+
+static const struct ip6_tnl_encap_ops gue_ip6tun_ops = {
+ .encap_hlen = gue_encap_hlen,
+ .build_header = gue6_build_header,
+};
+
+static int ip6_tnl_encap_add_fou_ops(void)
+{
+ int ret;
+
+ ret = ip6_tnl_encap_add_ops(&fou_ip6tun_ops, TUNNEL_ENCAP_FOU);
+ if (ret < 0) {
+ pr_err("can't add fou6 ops\n");
+ return ret;
+ }
+
+ ret = ip6_tnl_encap_add_ops(&gue_ip6tun_ops, TUNNEL_ENCAP_GUE);
+ if (ret < 0) {
+ pr_err("can't add gue6 ops\n");
+ ip6_tnl_encap_del_ops(&fou_ip6tun_ops, TUNNEL_ENCAP_FOU);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void ip6_tnl_encap_del_fou_ops(void)
+{
+ ip6_tnl_encap_del_ops(&fou_ip6tun_ops, TUNNEL_ENCAP_FOU);
+ ip6_tnl_encap_del_ops(&gue_ip6tun_ops, TUNNEL_ENCAP_GUE);
+}
+
+#else
+
+static int ip6_tnl_encap_add_fou_ops(void)
+{
+ return 0;
+}
+
+static void ip6_tnl_encap_del_fou_ops(void)
+{
+}
+
+#endif
+
+static int __init fou6_init(void)
+{
+ int ret;
+
+ ret = ip6_tnl_encap_add_fou_ops();
+
+ return ret;
+}
+
+static void __exit fou6_fini(void)
+{
+ ip6_tnl_encap_del_fou_ops();
+}
+
+module_init(fou6_init);
+module_exit(fou6_fini);
+MODULE_AUTHOR("Tom Herbert <therbert@google.com>");
+MODULE_LICENSE("GPL");
diff --git a/net/ipv6/ip6_tunnel_core.c b/net/ipv6/ip6_tunnel_core.c
new file mode 100644
index 0000000..5f5b79e
--- /dev/null
+++ b/net/ipv6/ip6_tunnel_core.c
@@ -0,0 +1,44 @@
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/if.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/net.h>
+#include <linux/in6.h>
+#include <net/ip6_tunnel.h>
+
+const struct ip6_tnl_encap_ops __rcu *
+ ip6tun_encaps[MAX_IPTUN_ENCAP_OPS] __read_mostly;
+EXPORT_SYMBOL(ip6tun_encaps);
+
+int ip6_tnl_encap_add_ops(const struct ip6_tnl_encap_ops *ops,
+ unsigned int num)
+{
+ if (num >= MAX_IPTUN_ENCAP_OPS)
+ return -ERANGE;
+
+ return !cmpxchg((const struct ip6_tnl_encap_ops **)
+ &ip6tun_encaps[num],
+ NULL, ops) ? 0 : -1;
+}
+EXPORT_SYMBOL(ip6_tnl_encap_add_ops);
+
+int ip6_tnl_encap_del_ops(const struct ip6_tnl_encap_ops *ops,
+ unsigned int num)
+{
+ int ret;
+
+ if (num >= MAX_IPTUN_ENCAP_OPS)
+ return -ERANGE;
+
+ ret = (cmpxchg((const struct ip6_tnl_encap_ops **)
+ &ip6tun_encaps[num],
+ ops, NULL) == ops) ? 0 : -1;
+
+ synchronize_net();
+
+ return ret;
+}
+EXPORT_SYMBOL(ip6_tnl_encap_del_ops);
+
--
2.8.0.rc2
^ permalink raw reply related
* [PATCH v2 next-next 09/12] ipv6: Change "final" protocol processing for encapsulation
From: Tom Herbert @ 2016-05-06 20:04 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
In-Reply-To: <1462565096-4076043-1-git-send-email-tom@herbertland.com>
When performing foo-over-UDP, UDP are receveived processed by the
encapsulation header which returns another protocol to process.
This may result in processing two (or more) protocols in the
loop that are marked as INET6_PROTO_FINAL. The actions taken
for hitting a final protocol, in particular the skb_postpull_rcsum
can only be performed.
This patch set adds a check of a final protocol has been seen. The
rules are:
- If the final protocol has not been seen any protocol is processed
(final and non-final). In the case of a final protocol, the final
actions are taken (like the skb_postpull_rcsum)
- If a final protocol has been seen (e.g. an encapsulating UDP
header) then no further non-final protocols are allowed
(e.g. extension headers). For more final protocols the
final actions are not taken (e.g. skb_postpull_rcsum).
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
net/ipv6/ip6_input.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 2a0258a..7d98d01 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -216,6 +216,7 @@ static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *sk
unsigned int nhoff;
int nexthdr;
bool raw;
+ bool have_final = false;
/*
* Parse extension headers
@@ -235,9 +236,21 @@ resubmit:
if (ipprot) {
int ret;
- if (ipprot->flags & INET6_PROTO_FINAL) {
+ if (have_final) {
+ if (!(ipprot->flags & INET6_PROTO_FINAL)) {
+ /* Once we've seen a final protocol don't
+ * allow encapsulation on any non-final
+ * ones. This allows foo in UDP encapsulation
+ * to work.
+ */
+ goto discard;
+ }
+ } else if (ipprot->flags & INET6_PROTO_FINAL) {
const struct ipv6hdr *hdr;
+ /* Only do this once for first final protocol */
+ have_final = true;
+
/* Free reference early: we don't need it any more,
and it may hold ip_conntrack module loaded
indefinitely. */
--
2.8.0.rc2
^ permalink raw reply related
* [PATCH v2 next-next 10/12] fou: Support IPv6 in fou
From: Tom Herbert @ 2016-05-06 20:04 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
In-Reply-To: <1462565096-4076043-1-git-send-email-tom@herbertland.com>
This patch adds receive path support for IPv6 with fou.
- Add address family to fou structure for open sockets. This supports
AF_INET and AF_INET6. Lookups for fou ports are performed on both the
port number and family.
- In fou and gue receive adjust tot_len in IPv4 header or payload_len
based on address family.
- Allow AF_INET6 in FOU_ATTR_AF netlink attribute.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
net/ipv4/fou.c | 47 +++++++++++++++++++++++++++++++++++------------
1 file changed, 35 insertions(+), 12 deletions(-)
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
index 971c8c6..75db828 100644
--- a/net/ipv4/fou.c
+++ b/net/ipv4/fou.c
@@ -21,6 +21,7 @@ struct fou {
u8 protocol;
u8 flags;
__be16 port;
+ u8 family;
u16 type;
struct list_head list;
struct rcu_head rcu;
@@ -47,14 +48,17 @@ static inline struct fou *fou_from_sock(struct sock *sk)
return sk->sk_user_data;
}
-static int fou_recv_pull(struct sk_buff *skb, size_t len)
+static int fou_recv_pull(struct sk_buff *skb, struct fou *fou, size_t len)
{
- struct iphdr *iph = ip_hdr(skb);
-
/* Remove 'len' bytes from the packet (UDP header and
* FOU header if present).
*/
- iph->tot_len = htons(ntohs(iph->tot_len) - len);
+ if (fou->family == AF_INET)
+ ip_hdr(skb)->tot_len = htons(ntohs(ip_hdr(skb)->tot_len) - len);
+ else
+ ipv6_hdr(skb)->payload_len =
+ htons(ntohs(ipv6_hdr(skb)->payload_len) - len);
+
__skb_pull(skb, len);
skb_postpull_rcsum(skb, udp_hdr(skb), len);
skb_reset_transport_header(skb);
@@ -68,7 +72,7 @@ static int fou_udp_recv(struct sock *sk, struct sk_buff *skb)
if (!fou)
return 1;
- if (fou_recv_pull(skb, sizeof(struct udphdr)))
+ if (fou_recv_pull(skb, fou, sizeof(struct udphdr)))
goto drop;
return -fou->protocol;
@@ -141,7 +145,11 @@ static int gue_udp_recv(struct sock *sk, struct sk_buff *skb)
hdrlen = sizeof(struct guehdr) + optlen;
- ip_hdr(skb)->tot_len = htons(ntohs(ip_hdr(skb)->tot_len) - len);
+ if (fou->family == AF_INET)
+ ip_hdr(skb)->tot_len = htons(ntohs(ip_hdr(skb)->tot_len) - len);
+ else
+ ipv6_hdr(skb)->payload_len =
+ htons(ntohs(ipv6_hdr(skb)->payload_len) - len);
/* Pull csum through the guehdr now . This can be used if
* there is a remote checksum offload.
@@ -424,7 +432,8 @@ static int fou_add_to_port_list(struct net *net, struct fou *fou)
mutex_lock(&fn->fou_lock);
list_for_each_entry(fout, &fn->fou_list, list) {
- if (fou->port == fout->port) {
+ if (fou->port == fout->port &&
+ fou->family == fout->family) {
mutex_unlock(&fn->fou_lock);
return -EALREADY;
}
@@ -469,8 +478,9 @@ static int fou_create(struct net *net, struct fou_cfg *cfg,
sk = sock->sk;
- fou->flags = cfg->flags;
fou->port = cfg->udp_config.local_udp_port;
+ fou->family = cfg->udp_config.family;
+ fou->flags = cfg->flags;
fou->type = cfg->type;
fou->sock = sock;
@@ -522,12 +532,13 @@ static int fou_destroy(struct net *net, struct fou_cfg *cfg)
{
struct fou_net *fn = net_generic(net, fou_net_id);
__be16 port = cfg->udp_config.local_udp_port;
+ u8 family = cfg->udp_config.family;
int err = -EINVAL;
struct fou *fou;
mutex_lock(&fn->fou_lock);
list_for_each_entry(fou, &fn->fou_list, list) {
- if (fou->port == port) {
+ if (fou->port == port && fou->family == family) {
fou_release(fou);
err = 0;
break;
@@ -565,8 +576,15 @@ static int parse_nl_config(struct genl_info *info,
if (info->attrs[FOU_ATTR_AF]) {
u8 family = nla_get_u8(info->attrs[FOU_ATTR_AF]);
- if (family != AF_INET)
- return -EINVAL;
+ switch (family) {
+ case AF_INET:
+ break;
+ case AF_INET6:
+ cfg->udp_config.ipv6_v6only = 1;
+ break;
+ default:
+ return -EAFNOSUPPORT;
+ }
cfg->udp_config.family = family;
}
@@ -657,6 +675,7 @@ static int fou_nl_cmd_get_port(struct sk_buff *skb, struct genl_info *info)
struct fou_cfg cfg;
struct fou *fout;
__be16 port;
+ u8 family;
int ret;
ret = parse_nl_config(info, &cfg);
@@ -666,6 +685,10 @@ static int fou_nl_cmd_get_port(struct sk_buff *skb, struct genl_info *info)
if (port == 0)
return -EINVAL;
+ family = cfg.udp_config.family;
+ if (family != AF_INET && family != AF_INET6)
+ return -EINVAL;
+
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
return -ENOMEM;
@@ -673,7 +696,7 @@ static int fou_nl_cmd_get_port(struct sk_buff *skb, struct genl_info *info)
ret = -ESRCH;
mutex_lock(&fn->fou_lock);
list_for_each_entry(fout, &fn->fou_list, list) {
- if (port == fout->port) {
+ if (port == fout->port && family == fout->family) {
ret = fou_dump_info(fout, info->snd_portid,
info->snd_seq, 0, msg,
info->genlhdr->cmd);
--
2.8.0.rc2
^ permalink raw reply related
* [PATCH v2 next-next 01/12] gso: Remove arbitrary checks for unsupported GSO
From: Tom Herbert @ 2016-05-06 20:04 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
In-Reply-To: <1462565096-4076043-1-git-send-email-tom@herbertland.com>
In several gso_segment functions there are checks of gso_type against
a seemingly arbitrary list of SKB_GSO_* flags. This seems like an
attempt to identify unsupported GSO types, but since the stack is
the one that set these GSO types in the first place this seems
unnecessary to do. If a combination isn't valid in the first
place that stack should not allow setting it.
This is a code simplication especially for add new GSO types.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
net/ipv4/af_inet.c | 18 ------------------
net/ipv4/gre_offload.c | 14 --------------
net/ipv4/tcp_offload.c | 19 -------------------
net/ipv4/udp_offload.c | 10 ----------
net/ipv6/ip6_offload.c | 18 ------------------
net/ipv6/udp_offload.c | 13 -------------
net/mpls/mpls_gso.c | 9 ---------
7 files changed, 101 deletions(-)
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 2e6e65f..7f08d45 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1205,24 +1205,6 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
int ihl;
int id;
- if (unlikely(skb_shinfo(skb)->gso_type &
- ~(SKB_GSO_TCPV4 |
- SKB_GSO_UDP |
- SKB_GSO_DODGY |
- SKB_GSO_TCP_ECN |
- SKB_GSO_GRE |
- SKB_GSO_GRE_CSUM |
- SKB_GSO_IPIP |
- SKB_GSO_SIT |
- SKB_GSO_TCPV6 |
- SKB_GSO_UDP_TUNNEL |
- SKB_GSO_UDP_TUNNEL_CSUM |
- SKB_GSO_TCP_FIXEDID |
- SKB_GSO_TUNNEL_REMCSUM |
- SKB_GSO_PARTIAL |
- 0)))
- goto out;
-
skb_reset_network_header(skb);
nhoff = skb_network_header(skb) - skb_mac_header(skb);
if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))
diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c
index e88190a..ecd1e09 100644
--- a/net/ipv4/gre_offload.c
+++ b/net/ipv4/gre_offload.c
@@ -26,20 +26,6 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
int gre_offset, outer_hlen;
bool need_csum, ufo;
- if (unlikely(skb_shinfo(skb)->gso_type &
- ~(SKB_GSO_TCPV4 |
- SKB_GSO_TCPV6 |
- SKB_GSO_UDP |
- SKB_GSO_DODGY |
- SKB_GSO_TCP_ECN |
- SKB_GSO_TCP_FIXEDID |
- SKB_GSO_GRE |
- SKB_GSO_GRE_CSUM |
- SKB_GSO_IPIP |
- SKB_GSO_SIT |
- SKB_GSO_PARTIAL)))
- goto out;
-
if (!skb->encapsulation)
goto out;
diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c
index 02737b6..5c59649 100644
--- a/net/ipv4/tcp_offload.c
+++ b/net/ipv4/tcp_offload.c
@@ -83,25 +83,6 @@ struct sk_buff *tcp_gso_segment(struct sk_buff *skb,
if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
/* Packet is from an untrusted source, reset gso_segs. */
- int type = skb_shinfo(skb)->gso_type;
-
- if (unlikely(type &
- ~(SKB_GSO_TCPV4 |
- SKB_GSO_DODGY |
- SKB_GSO_TCP_ECN |
- SKB_GSO_TCP_FIXEDID |
- SKB_GSO_TCPV6 |
- SKB_GSO_GRE |
- SKB_GSO_GRE_CSUM |
- SKB_GSO_IPIP |
- SKB_GSO_SIT |
- SKB_GSO_UDP_TUNNEL |
- SKB_GSO_UDP_TUNNEL_CSUM |
- SKB_GSO_TUNNEL_REMCSUM |
- 0) ||
- !(type & (SKB_GSO_TCPV4 |
- SKB_GSO_TCPV6))))
- goto out;
skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss);
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index 097060de..b556ef6 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -209,16 +209,6 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb,
if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
/* Packet is from an untrusted source, reset gso_segs. */
- int type = skb_shinfo(skb)->gso_type;
-
- if (unlikely(type & ~(SKB_GSO_UDP | SKB_GSO_DODGY |
- SKB_GSO_UDP_TUNNEL |
- SKB_GSO_UDP_TUNNEL_CSUM |
- SKB_GSO_TUNNEL_REMCSUM |
- SKB_GSO_IPIP |
- SKB_GSO_GRE | SKB_GSO_GRE_CSUM) ||
- !(type & (SKB_GSO_UDP))))
- goto out;
skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss);
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
index f5eb184..9ad743b 100644
--- a/net/ipv6/ip6_offload.c
+++ b/net/ipv6/ip6_offload.c
@@ -69,24 +69,6 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
bool encap, udpfrag;
int nhoff;
- if (unlikely(skb_shinfo(skb)->gso_type &
- ~(SKB_GSO_TCPV4 |
- SKB_GSO_UDP |
- SKB_GSO_DODGY |
- SKB_GSO_TCP_ECN |
- SKB_GSO_TCP_FIXEDID |
- SKB_GSO_TCPV6 |
- SKB_GSO_GRE |
- SKB_GSO_GRE_CSUM |
- SKB_GSO_IPIP |
- SKB_GSO_SIT |
- SKB_GSO_UDP_TUNNEL |
- SKB_GSO_UDP_TUNNEL_CSUM |
- SKB_GSO_TUNNEL_REMCSUM |
- SKB_GSO_PARTIAL |
- 0)))
- goto out;
-
skb_reset_network_header(skb);
nhoff = skb_network_header(skb) - skb_mac_header(skb);
if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h))))
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
index 5429f6b..ac858c4 100644
--- a/net/ipv6/udp_offload.c
+++ b/net/ipv6/udp_offload.c
@@ -36,19 +36,6 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
/* Packet is from an untrusted source, reset gso_segs. */
- int type = skb_shinfo(skb)->gso_type;
-
- if (unlikely(type & ~(SKB_GSO_UDP |
- SKB_GSO_DODGY |
- SKB_GSO_UDP_TUNNEL |
- SKB_GSO_UDP_TUNNEL_CSUM |
- SKB_GSO_TUNNEL_REMCSUM |
- SKB_GSO_GRE |
- SKB_GSO_GRE_CSUM |
- SKB_GSO_IPIP |
- SKB_GSO_SIT) ||
- !(type & (SKB_GSO_UDP))))
- goto out;
skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss);
diff --git a/net/mpls/mpls_gso.c b/net/mpls/mpls_gso.c
index bbcf604..6de1e13 100644
--- a/net/mpls/mpls_gso.c
+++ b/net/mpls/mpls_gso.c
@@ -26,15 +26,6 @@ static struct sk_buff *mpls_gso_segment(struct sk_buff *skb,
netdev_features_t mpls_features;
__be16 mpls_protocol;
- if (unlikely(skb_shinfo(skb)->gso_type &
- ~(SKB_GSO_TCPV4 |
- SKB_GSO_TCPV6 |
- SKB_GSO_UDP |
- SKB_GSO_DODGY |
- SKB_GSO_TCP_FIXEDID |
- SKB_GSO_TCP_ECN)))
- goto out;
-
/* Setup inner SKB. */
mpls_protocol = skb->protocol;
skb->protocol = skb->inner_protocol;
--
2.8.0.rc2
^ permalink raw reply related
* [PATCH v2 next-next 06/12] fou: Split out {fou,gue}_build_header
From: Tom Herbert @ 2016-05-06 20:04 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
In-Reply-To: <1462565096-4076043-1-git-send-email-tom@herbertland.com>
Create __fou_build_header and __gue_build_header. These implement the
protocol generic parts of building the fou and gue header.
fou_build_header and gue_build_header implement the IPv4 specific
functions and call the __*_build_header functions.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
include/net/fou.h | 8 ++++----
net/ipv4/fou.c | 47 +++++++++++++++++++++++++++++++++++++----------
2 files changed, 41 insertions(+), 14 deletions(-)
diff --git a/include/net/fou.h b/include/net/fou.h
index 19b8a0c..7d2fda2 100644
--- a/include/net/fou.h
+++ b/include/net/fou.h
@@ -11,9 +11,9 @@
size_t fou_encap_hlen(struct ip_tunnel_encap *e);
static size_t gue_encap_hlen(struct ip_tunnel_encap *e);
-int fou_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
- u8 *protocol, struct flowi4 *fl4);
-int gue_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
- u8 *protocol, struct flowi4 *fl4);
+int __fou_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
+ u8 *protocol, __be16 *sport, int type);
+int __gue_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
+ u8 *protocol, __be16 *sport, int type);
#endif
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
index a8b5cbf..971c8c6 100644
--- a/net/ipv4/fou.c
+++ b/net/ipv4/fou.c
@@ -778,6 +778,22 @@ static void fou_build_udp(struct sk_buff *skb, struct ip_tunnel_encap *e,
*protocol = IPPROTO_UDP;
}
+int __fou_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
+ u8 *protocol, __be16 *sport, int type)
+{
+ int err;
+
+ err = iptunnel_handle_offloads(skb, type);
+ if (err)
+ return err;
+
+ *sport = e->sport ? : udp_flow_src_port(dev_net(skb->dev),
+ skb, 0, 0, false);
+
+ return 0;
+}
+EXPORT_SYMBOL(__fou_build_header);
+
int fou_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
u8 *protocol, struct flowi4 *fl4)
{
@@ -786,26 +802,21 @@ int fou_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
__be16 sport;
int err;
- err = iptunnel_handle_offloads(skb, type);
+ err = __fou_build_header(skb, e, protocol, &sport, type);
if (err)
return err;
- sport = e->sport ? : udp_flow_src_port(dev_net(skb->dev),
- skb, 0, 0, false);
fou_build_udp(skb, e, fl4, protocol, sport);
return 0;
}
EXPORT_SYMBOL(fou_build_header);
-int gue_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
- u8 *protocol, struct flowi4 *fl4)
+int __gue_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
+ u8 *protocol, __be16 *sport, int type)
{
- int type = e->flags & TUNNEL_ENCAP_FLAG_CSUM ? SKB_GSO_UDP_TUNNEL_CSUM :
- SKB_GSO_UDP_TUNNEL;
struct guehdr *guehdr;
size_t hdrlen, optlen = 0;
- __be16 sport;
void *data;
bool need_priv = false;
int err;
@@ -824,8 +835,8 @@ int gue_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
return err;
/* Get source port (based on flow hash) before skb_push */
- sport = e->sport ? : udp_flow_src_port(dev_net(skb->dev),
- skb, 0, 0, false);
+ *sport = e->sport ? : udp_flow_src_port(dev_net(skb->dev),
+ skb, 0, 0, false);
hdrlen = sizeof(struct guehdr) + optlen;
@@ -870,6 +881,22 @@ int gue_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
}
+ return 0;
+}
+EXPORT_SYMBOL(__gue_build_header);
+
+int gue_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
+ u8 *protocol, struct flowi4 *fl4)
+{
+ int type = e->flags & TUNNEL_ENCAP_FLAG_CSUM ? SKB_GSO_UDP_TUNNEL_CSUM :
+ SKB_GSO_UDP_TUNNEL;
+ __be16 sport;
+ int err;
+
+ err = __gue_build_header(skb, e, protocol, &sport, type);
+ if (err)
+ return err;
+
fou_build_udp(skb, e, fl4, protocol, sport);
return 0;
--
2.8.0.rc2
^ permalink raw reply related
* [PATCH v2 next-next 03/12] gre6: Fix flag translations
From: Tom Herbert @ 2016-05-06 20:04 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
In-Reply-To: <1462565096-4076043-1-git-send-email-tom@herbertland.com>
GRE for IPv6 does not properly translate for GRE flags to tunnel
flags and vice versa. This patch fixes that.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
net/ipv6/ip6_gre.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 47b671a..70a1f72 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -799,8 +799,8 @@ static void ip6gre_tnl_parm_from_user(struct __ip6_tnl_parm *p,
p->link = u->link;
p->i_key = u->i_key;
p->o_key = u->o_key;
- p->i_flags = u->i_flags;
- p->o_flags = u->o_flags;
+ p->i_flags = gre_flags_to_tnl_flags(u->i_flags);
+ p->o_flags = gre_flags_to_tnl_flags(u->o_flags);
memcpy(p->name, u->name, sizeof(u->name));
}
@@ -817,8 +817,8 @@ static void ip6gre_tnl_parm_to_user(struct ip6_tnl_parm2 *u,
u->link = p->link;
u->i_key = p->i_key;
u->o_key = p->o_key;
- u->i_flags = p->i_flags;
- u->o_flags = p->o_flags;
+ u->i_flags = gre_tnl_flags_to_gre_flags(p->i_flags);
+ u->o_flags = gre_tnl_flags_to_gre_flags(p->o_flags);
memcpy(u->name, p->name, sizeof(u->name));
}
@@ -1217,10 +1217,12 @@ static void ip6gre_netlink_parms(struct nlattr *data[],
parms->link = nla_get_u32(data[IFLA_GRE_LINK]);
if (data[IFLA_GRE_IFLAGS])
- parms->i_flags = nla_get_be16(data[IFLA_GRE_IFLAGS]);
+ parms->i_flags = gre_flags_to_tnl_flags(
+ nla_get_be16(data[IFLA_GRE_IFLAGS]));
if (data[IFLA_GRE_OFLAGS])
- parms->o_flags = nla_get_be16(data[IFLA_GRE_OFLAGS]);
+ parms->o_flags = gre_flags_to_tnl_flags(
+ nla_get_be16(data[IFLA_GRE_OFLAGS]));
if (data[IFLA_GRE_IKEY])
parms->i_key = nla_get_be32(data[IFLA_GRE_IKEY]);
@@ -1412,8 +1414,10 @@ static int ip6gre_fill_info(struct sk_buff *skb, const struct net_device *dev)
struct __ip6_tnl_parm *p = &t->parms;
if (nla_put_u32(skb, IFLA_GRE_LINK, p->link) ||
- nla_put_be16(skb, IFLA_GRE_IFLAGS, p->i_flags) ||
- nla_put_be16(skb, IFLA_GRE_OFLAGS, p->o_flags) ||
+ nla_put_be16(skb, IFLA_GRE_IFLAGS,
+ gre_tnl_flags_to_gre_flags(p->i_flags)) ||
+ nla_put_be16(skb, IFLA_GRE_OFLAGS,
+ gre_tnl_flags_to_gre_flags(p->o_flags)) ||
nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) ||
nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) ||
nla_put_in6_addr(skb, IFLA_GRE_LOCAL, &p->laddr) ||
--
2.8.0.rc2
^ permalink raw reply related
* [PATCH v2 next-next 02/12] net: define gso types for IPx over IPv4 and IPv6
From: Tom Herbert @ 2016-05-06 20:04 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
In-Reply-To: <1462565096-4076043-1-git-send-email-tom@herbertland.com>
This patch defines two new GDO definitions SKB_GSO_IPXIP4 and
SKB_GSO_IPXIP6 along with corresponding NETIF_F_GSO_IPXIP4 and
NETIF_F_GSO_IPXIP6. These are used to described IP in IP
tunnel and what the outer protocol is. The inner protocol
can be deduced from other GSO types (e.g. SKB_GSO_TCPV4 and
SKB_GSO_TCPV6). The GSO types of SKB_GSO_IPIP and SKB_GSO_SIT
are removed (these are both instances of SKB_GSO_IPXIP4).
SKB_GSO_IPXIP6 will be used when support for GSO with IP
encapsulation over IPv6 is added.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 5 ++---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 4 ++--
drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +--
drivers/net/ethernet/intel/i40e/i40e_txrx.c | 3 +--
drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 3 +--
drivers/net/ethernet/intel/i40evf/i40evf_main.c | 3 +--
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 +--
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 3 +--
include/linux/netdev_features.h | 12 ++++++------
include/linux/netdevice.h | 4 ++--
include/linux/skbuff.h | 4 ++--
net/core/ethtool.c | 4 ++--
net/ipv4/af_inet.c | 2 +-
net/ipv4/ipip.c | 2 +-
net/ipv6/ip6_offload.c | 4 ++--
net/ipv6/sit.c | 4 ++--
net/netfilter/ipvs/ip_vs_xmit.c | 11 ++---------
17 files changed, 30 insertions(+), 44 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index d465bd7..0a5b770 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -13259,12 +13259,11 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev,
NETIF_F_RXHASH | NETIF_F_HW_VLAN_CTAG_TX;
if (!chip_is_e1x) {
dev->hw_features |= NETIF_F_GSO_GRE | NETIF_F_GSO_UDP_TUNNEL |
- NETIF_F_GSO_IPIP | NETIF_F_GSO_SIT;
+ NETIF_F_GSO_IPXIP4;
dev->hw_enc_features =
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG |
NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 |
- NETIF_F_GSO_IPIP |
- NETIF_F_GSO_SIT |
+ NETIF_F_GSO_IPXIP4 |
NETIF_F_GSO_GRE | NETIF_F_GSO_UDP_TUNNEL;
}
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index fd85b6d..e449228 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -6218,7 +6218,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG |
NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
- NETIF_F_GSO_IPIP | NETIF_F_GSO_SIT |
+ NETIF_F_GSO_IPXIP4 |
NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM |
NETIF_F_GSO_PARTIAL | NETIF_F_RXHASH |
NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_GRO;
@@ -6228,7 +6228,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM |
- NETIF_F_GSO_IPIP | NETIF_F_GSO_SIT |
+ NETIF_F_GSO_IPXIP4;
NETIF_F_GSO_PARTIAL;
dev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_GSO_GRE_CSUM;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index f6da6b7..c2a4c10 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -9131,8 +9131,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
NETIF_F_TSO6 |
NETIF_F_GSO_GRE |
NETIF_F_GSO_GRE_CSUM |
- NETIF_F_GSO_IPIP |
- NETIF_F_GSO_SIT |
+ NETIF_F_GSO_IPXIP4 |
NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_GSO_PARTIAL |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index 2765d7e..4a3d60a 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -2302,8 +2302,7 @@ static int i40e_tso(struct sk_buff *skb, u8 *hdr_len, u64 *cd_type_cmd_tso_mss)
if (skb_shinfo(skb)->gso_type & (SKB_GSO_GRE |
SKB_GSO_GRE_CSUM |
- SKB_GSO_IPIP |
- SKB_GSO_SIT |
+ SKB_GSO_IPXIP4 |
SKB_GSO_UDP_TUNNEL |
SKB_GSO_UDP_TUNNEL_CSUM)) {
if (!(skb_shinfo(skb)->gso_type & SKB_GSO_PARTIAL) &&
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
index ede8dfc..aaccb7e 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
@@ -1567,8 +1567,7 @@ static int i40e_tso(struct sk_buff *skb, u8 *hdr_len, u64 *cd_type_cmd_tso_mss)
if (skb_shinfo(skb)->gso_type & (SKB_GSO_GRE |
SKB_GSO_GRE_CSUM |
- SKB_GSO_IPIP |
- SKB_GSO_SIT |
+ SKB_GSO_IPXIP4 |
SKB_GSO_UDP_TUNNEL |
SKB_GSO_UDP_TUNNEL_CSUM)) {
if (!(skb_shinfo(skb)->gso_type & SKB_GSO_PARTIAL) &&
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index 9f0bd7a..bfd0962 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -2241,8 +2241,7 @@ int i40evf_process_config(struct i40evf_adapter *adapter)
NETIF_F_TSO6 |
NETIF_F_GSO_GRE |
NETIF_F_GSO_GRE_CSUM |
- NETIF_F_GSO_IPIP |
- NETIF_F_GSO_SIT |
+ NETIF_F_GSO_IPXIP4 |
NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_GSO_PARTIAL |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index d08fbcf..28e3b5a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -9482,8 +9482,7 @@ skip_sriov:
#define IXGBE_GSO_PARTIAL_FEATURES (NETIF_F_GSO_GRE | \
NETIF_F_GSO_GRE_CSUM | \
- NETIF_F_GSO_IPIP | \
- NETIF_F_GSO_SIT | \
+ NETIF_F_GSO_IPXIP4 | \
NETIF_F_GSO_UDP_TUNNEL | \
NETIF_F_GSO_UDP_TUNNEL_CSUM)
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 5e348b1..d86e511 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -4062,8 +4062,7 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
#define IXGBEVF_GSO_PARTIAL_FEATURES (NETIF_F_GSO_GRE | \
NETIF_F_GSO_GRE_CSUM | \
- NETIF_F_GSO_IPIP | \
- NETIF_F_GSO_SIT | \
+ NETIF_F_GSO_IPXIP4 | \
NETIF_F_GSO_UDP_TUNNEL | \
NETIF_F_GSO_UDP_TUNNEL_CSUM)
diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index bc87362..aa7b240 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -44,8 +44,8 @@ enum {
NETIF_F_FSO_BIT, /* ... FCoE segmentation */
NETIF_F_GSO_GRE_BIT, /* ... GRE with TSO */
NETIF_F_GSO_GRE_CSUM_BIT, /* ... GRE with csum with TSO */
- NETIF_F_GSO_IPIP_BIT, /* ... IPIP tunnel with TSO */
- NETIF_F_GSO_SIT_BIT, /* ... SIT tunnel with TSO */
+ NETIF_F_GSO_IPXIP4_BIT, /* ... IP4 or IP6 over IP4 with TSO */
+ NETIF_F_GSO_IPXIP6_BIT, /* ... IP4 or IP6 over IP6 with TSO */
NETIF_F_GSO_UDP_TUNNEL_BIT, /* ... UDP TUNNEL with TSO */
NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT,/* ... UDP TUNNEL with TSO & CSUM */
NETIF_F_GSO_PARTIAL_BIT, /* ... Only segment inner-most L4
@@ -121,8 +121,8 @@ enum {
#define NETIF_F_RXALL __NETIF_F(RXALL)
#define NETIF_F_GSO_GRE __NETIF_F(GSO_GRE)
#define NETIF_F_GSO_GRE_CSUM __NETIF_F(GSO_GRE_CSUM)
-#define NETIF_F_GSO_IPIP __NETIF_F(GSO_IPIP)
-#define NETIF_F_GSO_SIT __NETIF_F(GSO_SIT)
+#define NETIF_F_GSO_IPXIP4 __NETIF_F(GSO_IPXIP4)
+#define NETIF_F_GSO_IPXIP6 __NETIF_F(GSO_IPXIP6)
#define NETIF_F_GSO_UDP_TUNNEL __NETIF_F(GSO_UDP_TUNNEL)
#define NETIF_F_GSO_UDP_TUNNEL_CSUM __NETIF_F(GSO_UDP_TUNNEL_CSUM)
#define NETIF_F_TSO_MANGLEID __NETIF_F(TSO_MANGLEID)
@@ -200,8 +200,8 @@ enum {
#define NETIF_F_GSO_ENCAP_ALL (NETIF_F_GSO_GRE | \
NETIF_F_GSO_GRE_CSUM | \
- NETIF_F_GSO_IPIP | \
- NETIF_F_GSO_SIT | \
+ NETIF_F_GSO_IPXIP4 | \
+ NETIF_F_GSO_IPXIP6 | \
NETIF_F_GSO_UDP_TUNNEL | \
NETIF_F_GSO_UDP_TUNNEL_CSUM)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 63580e6..8b1eedc 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -4005,8 +4005,8 @@ static inline bool net_gso_ok(netdev_features_t features, int gso_type)
BUILD_BUG_ON(SKB_GSO_FCOE != (NETIF_F_FSO >> NETIF_F_GSO_SHIFT));
BUILD_BUG_ON(SKB_GSO_GRE != (NETIF_F_GSO_GRE >> NETIF_F_GSO_SHIFT));
BUILD_BUG_ON(SKB_GSO_GRE_CSUM != (NETIF_F_GSO_GRE_CSUM >> NETIF_F_GSO_SHIFT));
- BUILD_BUG_ON(SKB_GSO_IPIP != (NETIF_F_GSO_IPIP >> NETIF_F_GSO_SHIFT));
- BUILD_BUG_ON(SKB_GSO_SIT != (NETIF_F_GSO_SIT >> NETIF_F_GSO_SHIFT));
+ BUILD_BUG_ON(SKB_GSO_IPXIP4 != (NETIF_F_GSO_IPXIP4 >> NETIF_F_GSO_SHIFT));
+ BUILD_BUG_ON(SKB_GSO_IPXIP6 != (NETIF_F_GSO_IPXIP6 >> NETIF_F_GSO_SHIFT));
BUILD_BUG_ON(SKB_GSO_UDP_TUNNEL != (NETIF_F_GSO_UDP_TUNNEL >> NETIF_F_GSO_SHIFT));
BUILD_BUG_ON(SKB_GSO_UDP_TUNNEL_CSUM != (NETIF_F_GSO_UDP_TUNNEL_CSUM >> NETIF_F_GSO_SHIFT));
BUILD_BUG_ON(SKB_GSO_PARTIAL != (NETIF_F_GSO_PARTIAL >> NETIF_F_GSO_SHIFT));
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index c413c58..65968a9 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -471,9 +471,9 @@ enum {
SKB_GSO_GRE_CSUM = 1 << 8,
- SKB_GSO_IPIP = 1 << 9,
+ SKB_GSO_IPXIP4 = 1 << 9,
- SKB_GSO_SIT = 1 << 10,
+ SKB_GSO_IPXIP6 = 1 << 10,
SKB_GSO_UDP_TUNNEL = 1 << 11,
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index bdb4013..f403481 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -84,8 +84,8 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN]
[NETIF_F_FSO_BIT] = "tx-fcoe-segmentation",
[NETIF_F_GSO_GRE_BIT] = "tx-gre-segmentation",
[NETIF_F_GSO_GRE_CSUM_BIT] = "tx-gre-csum-segmentation",
- [NETIF_F_GSO_IPIP_BIT] = "tx-ipip-segmentation",
- [NETIF_F_GSO_SIT_BIT] = "tx-sit-segmentation",
+ [NETIF_F_GSO_IPXIP4_BIT] = "tx-ipxip4-segmentation",
+ [NETIF_F_GSO_IPXIP6_BIT] = "tx-ipxip6-segmentation",
[NETIF_F_GSO_UDP_TUNNEL_BIT] = "tx-udp_tnl-segmentation",
[NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT] = "tx-udp_tnl-csum-segmentation",
[NETIF_F_GSO_PARTIAL_BIT] = "tx-gso-partial",
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 7f08d45..25040b1 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1483,7 +1483,7 @@ out_unlock:
static int ipip_gro_complete(struct sk_buff *skb, int nhoff)
{
skb->encapsulation = 1;
- skb_shinfo(skb)->gso_type |= SKB_GSO_IPIP;
+ skb_shinfo(skb)->gso_type |= SKB_GSO_IPXIP4;
return inet_gro_complete(skb, nhoff);
}
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 9282748..9783701 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -219,7 +219,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
if (unlikely(skb->protocol != htons(ETH_P_IP)))
goto tx_error;
- if (iptunnel_handle_offloads(skb, SKB_GSO_IPIP))
+ if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP4))
goto tx_error;
skb_set_inner_ipproto(skb, IPPROTO_IPIP);
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
index 9ad743b..787e55f 100644
--- a/net/ipv6/ip6_offload.c
+++ b/net/ipv6/ip6_offload.c
@@ -86,7 +86,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
proto = ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr);
if (skb->encapsulation &&
- skb_shinfo(skb)->gso_type & (SKB_GSO_SIT|SKB_GSO_IPIP))
+ skb_shinfo(skb)->gso_type & (SKB_GSO_IPXIP4 | SKB_GSO_IPXIP6))
udpfrag = proto == IPPROTO_UDP && encap;
else
udpfrag = proto == IPPROTO_UDP && !skb->encapsulation;
@@ -294,7 +294,7 @@ out_unlock:
static int sit_gro_complete(struct sk_buff *skb, int nhoff)
{
skb->encapsulation = 1;
- skb_shinfo(skb)->gso_type |= SKB_GSO_SIT;
+ skb_shinfo(skb)->gso_type |= SKB_GSO_IPXIP4;
return ipv6_gro_complete(skb, nhoff);
}
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index a13d8c1..0a5a255 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -913,7 +913,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
goto tx_error;
}
- if (iptunnel_handle_offloads(skb, SKB_GSO_SIT)) {
+ if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP4)) {
ip_rt_put(rt);
goto tx_error;
}
@@ -1000,7 +1000,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
struct ip_tunnel *tunnel = netdev_priv(dev);
const struct iphdr *tiph = &tunnel->parms.iph;
- if (iptunnel_handle_offloads(skb, SKB_GSO_IPIP))
+ if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP4))
goto tx_error;
skb_set_inner_ipproto(skb, IPPROTO_IPIP);
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 6d19d2e..f646ef6 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -932,16 +932,9 @@ error:
static inline int __tun_gso_type_mask(int encaps_af, int orig_af)
{
- if (encaps_af == AF_INET) {
- if (orig_af == AF_INET)
- return SKB_GSO_IPIP;
+ if (encaps_af == AF_INET)
+ return SKB_GSO_IPXIP4;
- return SKB_GSO_SIT;
- }
-
- /* GSO: we need to provide proper SKB_GSO_ value for IPv6:
- * SKB_GSO_SIT/IPV6
- */
return 0;
}
--
2.8.0.rc2
^ permalink raw reply related
* [PATCH v2 next-next 00/12] ipv6: Enable GUEoIPv6 and more fixes for v6 tunneling
From: Tom Herbert @ 2016-05-06 20:04 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
This patch set:
- Fixes GRE6 to process translate flags correctly from configuration
- Adds support for GSO and GRO for ip6ip6 and ip4ip6
- Add support for FOU and GUE in IPv6
- Support GRE, ip6ip6 and ip4ip6 over FOU/GUE
- Fixes ip6_input to deal with UDP encapsulations
- Some other minor fixes
v2:
- Removed a check of GSO types in MPLS
- Define GSO type SKB_GSO_IPXIP6 and SKB_GSO_IPXIP4 (based on input
from Alexander)
- Don't define GSO types specifally for IP6IP6 and IP4IP6, above
fix makes that uncessary
- Don't bother clearing encapsulation flag in UDP tunnel segment
(another item suggested by Alexander).
Tested:
Tested a variety of case, but not the full matrix (which is quite
large now). Most of the obivous cases (e.g. GRE) work fine. Still
some issues probably with GSO/GRO being effective in all cases.
- IPv4/GRE/GUE/IPv6 with RCO
1 TCP_STREAM
6616 Mbps
200 TCP_RR
1244043 tps
141/243/446 90/95/99% latencies
86.61% CPU utilization
- IPv6/GRE/GUE/IPv6 with RCO
1 TCP_STREAM
6940 Mbps
200 TCP_RR
1270903 tps
138/236/440 90/95/99% latencies
87.51% CPU utilization
- IP6IP6
1 TCP_STREAM
2576 Mbps
200 TCP_RR
498981 tps
388/498/631 90/95/99% latencies
19.75% CPU utilization (1 CPU saturated)
- IP6IP6/GUE/IPv6 with RCO
1 TCP_STREAM
1854 Mbps
200 TCP_RR
1233818 tps
143/244/451 90/95/99% latencies
87.57 CPU utilization
- IP4IP6
1 TCP_STREAM
200 TCP_RR
763774 tps
250/318/466 90/95/99% latencies
35.25% CPU utilization (1 CPU saturated)
- GRE with keyid
200 TCP_RR
744173 tps
258/332/461 90/95/99% latencies
34.59% CPU utilization (1 CPU saturated)
Tom Herbert (12):
gso: Remove arbitrary checks for unsupported GSO
net: define gso types for IPx over IPv4 and IPv6
gre6: Fix flag translations
udp: Don't set skb->encapsulation with RCO
fou: Call setup_udp_tunnel_sock
fou: Split out {fou,gue}_build_header
fou: Add encap ops for IPv6 tunnels
ipv6: Fix nexthdr for reinjection
ipv6: Change "final" protocol processing for encapsulation
fou: Support IPv6 in fou
ip6_tun: Add infrastructure for doing encapsulation
ip6_gre: Add support for fou/gue encapsulation
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 5 +-
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 4 +-
drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +-
drivers/net/ethernet/intel/i40e/i40e_txrx.c | 3 +-
drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 3 +-
drivers/net/ethernet/intel/i40evf/i40evf_main.c | 3 +-
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 +-
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 3 +-
include/linux/netdev_features.h | 12 +-
include/linux/netdevice.h | 4 +-
include/linux/skbuff.h | 4 +-
include/net/fou.h | 10 +-
include/net/ip6_tunnel.h | 22 +++-
net/core/ethtool.c | 4 +-
net/ipv4/af_inet.c | 20 +--
net/ipv4/fou.c | 144 +++++++++++++---------
net/ipv4/gre_offload.c | 14 ---
net/ipv4/ipip.c | 2 +-
net/ipv4/tcp_offload.c | 19 ---
net/ipv4/udp_offload.c | 19 +--
net/ipv6/Makefile | 4 +-
net/ipv6/fou6.c | 140 +++++++++++++++++++++
net/ipv6/ip6_gre.c | 95 ++++++++++++--
net/ipv6/ip6_input.c | 24 +++-
net/ipv6/ip6_offload.c | 22 +---
net/ipv6/ip6_tunnel.c | 4 +
net/ipv6/ip6_tunnel_core.c | 108 ++++++++++++++++
net/ipv6/sit.c | 4 +-
net/ipv6/udp_offload.c | 13 --
net/mpls/mpls_gso.c | 9 --
net/netfilter/ipvs/ip_vs_xmit.c | 11 +-
31 files changed, 511 insertions(+), 224 deletions(-)
create mode 100644 net/ipv6/fou6.c
create mode 100644 net/ipv6/ip6_tunnel_core.c
--
2.8.0.rc2
^ permalink raw reply
* [PATCH v2 next-next 11/12] ip6_tun: Add infrastructure for doing encapsulation
From: Tom Herbert @ 2016-05-06 20:04 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
In-Reply-To: <1462565096-4076043-1-git-send-email-tom@herbertland.com>
Add encap_hlen and ip_tunnel_encap structure to ip6_tnl. Add functions
for getting encap hlen, setting up encap on a tunnel, performing
encapsulation operation.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
include/net/ip6_tunnel.h | 8 +++++-
net/ipv6/ip6_tunnel.c | 4 +++
net/ipv6/ip6_tunnel_core.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 75 insertions(+), 1 deletion(-)
diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h
index 1c14c27..1b8db86 100644
--- a/include/net/ip6_tunnel.h
+++ b/include/net/ip6_tunnel.h
@@ -66,10 +66,16 @@ struct ip6_tnl {
__u32 o_seqno; /* The last output seqno */
int hlen; /* tun_hlen + encap_hlen */
int tun_hlen; /* Precalculated header length */
+ int encap_hlen; /* Encap header length (FOU,GUE) */
+ struct ip_tunnel_encap encap;
int mlink;
-
};
+int ip6_tnl_encap_setup(struct ip6_tnl *t,
+ struct ip_tunnel_encap *ipencap);
+int ip6_tnl_encap(struct sk_buff *skb, struct ip6_tnl *t,
+ u8 *protocol, struct flowi6 *fl6);
+
/* Tunnel encapsulation limit destination sub-option */
struct ipv6_tlv_tnl_enc_lim {
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index ade55af..2c096ab 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1013,6 +1013,10 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
unsigned int max_headroom = sizeof(struct ipv6hdr);
int err = -1;
+ err = ip6_tnl_encap(skb, t, &proto, fl6);
+ if (err)
+ return err;
+
/* NBMA tunnel */
if (ipv6_addr_any(&t->parms.raddr)) {
struct in6_addr *addr6;
diff --git a/net/ipv6/ip6_tunnel_core.c b/net/ipv6/ip6_tunnel_core.c
index 5f5b79e..94aa414 100644
--- a/net/ipv6/ip6_tunnel_core.c
+++ b/net/ipv6/ip6_tunnel_core.c
@@ -42,3 +42,67 @@ int ip6_tnl_encap_del_ops(const struct ip6_tnl_encap_ops *ops,
}
EXPORT_SYMBOL(ip6_tnl_encap_del_ops);
+static int ip6_encap_hlen(struct ip_tunnel_encap *e)
+{
+ const struct ip6_tnl_encap_ops *ops;
+ int hlen = -EINVAL;
+
+ if (e->type == TUNNEL_ENCAP_NONE)
+ return 0;
+
+ if (e->type >= MAX_IPTUN_ENCAP_OPS)
+ return -EINVAL;
+
+ rcu_read_lock();
+ ops = rcu_dereference(ip6tun_encaps[e->type]);
+ if (likely(ops && ops->encap_hlen))
+ hlen = ops->encap_hlen(e);
+ rcu_read_unlock();
+
+ return hlen;
+}
+
+int ip6_tnl_encap_setup(struct ip6_tnl *t,
+ struct ip_tunnel_encap *ipencap)
+{
+ int hlen;
+
+ memset(&t->encap, 0, sizeof(t->encap));
+
+ hlen = ip6_encap_hlen(ipencap);
+ if (hlen < 0)
+ return hlen;
+
+ t->encap.type = ipencap->type;
+ t->encap.sport = ipencap->sport;
+ t->encap.dport = ipencap->dport;
+ t->encap.flags = ipencap->flags;
+
+ t->encap_hlen = hlen;
+ t->hlen = t->encap_hlen + t->tun_hlen;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ip6_tnl_encap_setup);
+
+int ip6_tnl_encap(struct sk_buff *skb, struct ip6_tnl *t,
+ u8 *protocol, struct flowi6 *fl6)
+{
+ const struct ip6_tnl_encap_ops *ops;
+ int ret = -EINVAL;
+
+ if (t->encap.type == TUNNEL_ENCAP_NONE)
+ return 0;
+
+ if (t->encap.type >= MAX_IPTUN_ENCAP_OPS)
+ return -EINVAL;
+
+ rcu_read_lock();
+ ops = rcu_dereference(ip6tun_encaps[t->encap.type]);
+ if (likely(ops && ops->build_header))
+ ret = ops->build_header(skb, &t->encap, protocol, fl6);
+ rcu_read_unlock();
+
+ return ret;
+}
+EXPORT_SYMBOL(ip6_tnl_encap);
--
2.8.0.rc2
^ permalink raw reply related
* [PATCH v2 next-next 08/12] ipv6: Fix nexthdr for reinjection
From: Tom Herbert @ 2016-05-06 20:04 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
In-Reply-To: <1462565096-4076043-1-git-send-email-tom@herbertland.com>
In ip6_input_finish the protocol handle returns a value greater than
zero the packet needs to be resubmitted using the returned protocol.
The returned protocol is being ignored and each time through resubmit
nexthdr is taken from an offest in the packet. This patch fixes that
so that nexthdr is taken from return value of the protocol handler.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
net/ipv6/ip6_input.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 6ed5601..2a0258a 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -222,13 +222,14 @@ static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *sk
*/
rcu_read_lock();
-resubmit:
+
idev = ip6_dst_idev(skb_dst(skb));
if (!pskb_pull(skb, skb_transport_offset(skb)))
goto discard;
nhoff = IP6CB(skb)->nhoff;
nexthdr = skb_network_header(skb)[nhoff];
+resubmit:
raw = raw6_local_deliver(skb, nexthdr);
ipprot = rcu_dereference(inet6_protos[nexthdr]);
if (ipprot) {
@@ -256,10 +257,12 @@ resubmit:
goto discard;
ret = ipprot->handler(skb);
- if (ret > 0)
+ if (ret > 0) {
+ nexthdr = ret;
goto resubmit;
- else if (ret == 0)
+ } else if (ret == 0) {
__IP6_INC_STATS(net, idev, IPSTATS_MIB_INDELIVERS);
+ }
} else {
if (!raw) {
if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
--
2.8.0.rc2
^ permalink raw reply related
* [PATCH v2 next-next 04/12] udp: Don't set skb->encapsulation with RCO
From: Tom Herbert @ 2016-05-06 20:04 UTC (permalink / raw)
To: davem, netdev; +Cc: kernel-team
In-Reply-To: <1462565096-4076043-1-git-send-email-tom@herbertland.com>
When RCO is in effect we want to ensure that the outer checksum is
properly offloaded. Don't set skb->encapsulation in this case to
ensure that checksum offload is later considered for hw_features
instead of hw_enc_features.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
net/ipv4/udp_offload.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index b556ef6..92a9222 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -94,11 +94,12 @@ static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb,
do {
unsigned int len;
- if (remcsum)
+ if (remcsum) {
skb->ip_summed = CHECKSUM_NONE;
-
- /* Set up inner headers if we are offloading inner checksum */
- if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ /* Set up inner headers if we are offloading inner
+ * checksum
+ */
skb_reset_inner_headers(skb);
skb->encapsulation = 1;
}
--
2.8.0.rc2
^ permalink raw reply related
* Re: [PATCH net-next] ipv4: tcp: ip_send_unicast_reply() is not BH safe
From: David Miller @ 2016-05-06 20:03 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, andreslc, edumazet
In-Reply-To: <1462553178.13075.56.camel@edumazet-glaptop3.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 06 May 2016 09:46:18 -0700
> From: Eric Dumazet <edumazet@google.com>
>
> I forgot that ip_send_unicast_reply() is not BH safe (yet).
>
> Disabling preemption before calling it was not a good move.
>
> Fixes: c10d9310edf5 ("tcp: do not assume TCP code is non preemptible")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Reported-by: Andres Lagar-Cavilla <andreslc@google.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH net-next 0/7] bpf: introduce direct packet access
From: David Miller @ 2016-05-06 20:02 UTC (permalink / raw)
To: ast; +Cc: daniel, netdev, kernel-team
In-Reply-To: <1462502955-1731797-1-git-send-email-ast@fb.com>
From: Alexei Starovoitov <ast@fb.com>
Date: Thu, 5 May 2016 19:49:08 -0700
> This set of patches introduce 'direct packet access' from
> cls_bpf and act_bpf programs (which are root only).
Series applied, thanks Alexei.
^ permalink raw reply
* Re: [patch net 0/3] mlxsw: Couple of fixes
From: David Miller @ 2016-05-06 20:00 UTC (permalink / raw)
To: jiri; +Cc: netdev, idosch, eladr, yotamg, ogerlitz
In-Reply-To: <1462526244-11898-1-git-send-email-jiri@resnulli.us>
From: Jiri Pirko <jiri@resnulli.us>
Date: Fri, 6 May 2016 11:17:21 +0200
> From: Jiri Pirko <jiri@mellanox.com>
>
> Ido Schimmel (2):
> mlxsw: spectrum: Fix rollback order in LAG join failure
> mlxsw: spectrum: Add missing rollback in flood configuration
>
> Jiri Pirko (1):
> mlxsw: spectrum: Fix ordering in mlxsw_sp_fini
What tree is this for? Because on 'net' this makes the build fail.
drivers/net/ethernet/mellanox/mlxsw/spectrum.c: In function ‘mlxsw_sp_fini’:
drivers/net/ethernet/mellanox/mlxsw/spectrum.c:2162:2: error: implicit declaration of function ‘mlxsw_sp_buffers_fini’ [-Werror=implicit-function-declaration]
^ permalink raw reply
* Re: [net-next 00/11][pull request] 40GbE Intel Wired LAN Driver Updates 2016-05-05
From: David Miller @ 2016-05-06 19:55 UTC (permalink / raw)
To: jeffrey.t.kirsher; +Cc: netdev, nhorman, sassmann, jogreene, john.ronciak
In-Reply-To: <1462518228-30527-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Fri, 6 May 2016 00:03:37 -0700
> This series contains updates to i40e and i40evf.
Looks good, pulled, thanks!
^ permalink raw reply
* Re: [PATCH net v3 2/2] udp_offload: Set encapsulation before inner completes.
From: Alexander Duyck @ 2016-05-06 19:52 UTC (permalink / raw)
To: David Miller; +Cc: Jarno Rajahalme, Netdev, Tom Herbert
In-Reply-To: <20160506.153412.1756777490005831525.davem@davemloft.net>
On Fri, May 6, 2016 at 12:34 PM, David Miller <davem@davemloft.net> wrote:
> From: Jarno Rajahalme <jarno@ovn.org>
> Date: Tue, 3 May 2016 16:10:21 -0700
>
>> UDP tunnel segmentation code relies on the inner offsets being set for
>> an UDP tunnel GSO packet, but the inner *_complete() functions will
>> set the inner offsets only if 'encapsulation' is set before calling
>> them. Currently, udp_gro_complete() sets 'encapsulation' only after
>> the inner *_complete() functions are done. This causes the inner
>> offsets having invalid values after udp_gro_complete() returns, which
>> in turn will make it impossible to properly segment the packet in case
>> it needs to be forwarded, which would be visible to the user either as
>> invalid packets being sent or as packet loss.
>>
>> This patch fixes this by setting skb's 'encapsulation' in
>> udp_gro_complete() before calling into the inner complete functions,
>> and by making each possible UDP tunnel gro_complete() callback set the
>> inner_mac_header to the beginning of the tunnel payload.
>>
>> Signed-off-by: Jarno Rajahalme <jarno@ovn.org>
>> ---
>> v3: Added setting inner_mac_header from all possible callbacks to cover
>> cases where there is no inner mac header.
>
> Alex and Tom, can you please review this new version since you guys had
> so much feedback for v2?
>
> THanks.
I had reviewed it a day or so ago. It did address the issues I saw
with the original patch, and from what I can tell it is fixing the
original issue reported.
Reviewed-by: Alexander Duyck <aduyck@mirantis.com>
^ permalink raw reply
* Re: [PATCH net-next v2] net: vrf: Create FIB tables on link create
From: David Miller @ 2016-05-06 19:52 UTC (permalink / raw)
To: dsa; +Cc: netdev
In-Reply-To: <1462423572-15722-1-git-send-email-dsa@cumulusnetworks.com>
From: David Ahern <dsa@cumulusnetworks.com>
Date: Wed, 4 May 2016 21:46:12 -0700
> Tables have to exist for VRFs to function. Ensure they exist
> when VRF device is created.
>
> Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
> ---
> v2
> - create table before rt6 allocation per comment from DaveM
Yep, this looks better, applied.
^ permalink raw reply
* Re: [PATCH net 1/1] qede: prevent chip hang when increasing channels
From: David Miller @ 2016-05-06 19:51 UTC (permalink / raw)
To: sudarsana.kalluru; +Cc: netdev, Yuval.Mintz
In-Reply-To: <1462422916-25584-1-git-send-email-sudarsana.kalluru@qlogic.com>
From: Sudarsana Reddy Kalluru <sudarsana.kalluru@qlogic.com>
Date: Thu, 5 May 2016 00:35:16 -0400
> qede requires qed to provide enough resources to accommodate 16 combined
> channels, but that upper-bound isn't actually being enforced by it.
> Instead, qed inform back to qede how many channels can be opened based on
> available resources - but that calculation doesn't really take into account
> the resources requested by qede; Instead it considers other FW/HW available
> resources.
>
> As a result, if a user would increase the number of channels to more than
> 16 [e.g., using ethtool] the chip would hang.
>
> This change increments the resources requested by qede to 64 combined
> channels instead of 16; This value is an upper bound on the possible
> available channels [due to other FW/HW resources].
>
> Signed-off-by: Sudarsana Reddy Kalluru <sudarsana.kalluru@qlogic.com>
> Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com>
Applied.
^ permalink raw reply
* Re: [PATCH] net: ipv6: tcp reset, icmp need to consider L3 domain
From: David Miller @ 2016-05-06 19:49 UTC (permalink / raw)
To: dsa; +Cc: netdev
In-Reply-To: <1462422368-10822-1-git-send-email-dsa@cumulusnetworks.com>
From: David Ahern <dsa@cumulusnetworks.com>
Date: Wed, 4 May 2016 21:26:08 -0700
> Responses for packets to unused ports are getting lost with L3 domains.
>
> IPv4 has ip_send_unicast_reply for sending TCP responses which accounts
> for L3 domains; update the IPv6 counterpart tcp_v6_send_response.
> For icmp the L3 master check needs to be moved up in icmp6_send
> to properly respond to UDP packets to a port with no listener.
>
> Fixes: ca254490c8df ("net: Add VRF support to IPv6 stack")
> Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Applied and queued up for -stable, thanks.
^ permalink raw reply
* Re: [PATCH net v3] vlan: Propagate MAC address to VLANs
From: Alexander Duyck @ 2016-05-06 19:48 UTC (permalink / raw)
To: Mike Manning; +Cc: Netdev
In-Reply-To: <572CF258.4070309@brocade.com>
On Fri, May 6, 2016 at 12:36 PM, Mike Manning <mmanning@brocade.com> wrote:
> On 05/06/2016 06:02 PM, Alexander Duyck wrote:
>> On Fri, May 6, 2016 at 6:26 AM, Mike Manning <mmanning@brocade.com> wrote:
>>> The MAC address of the physical interface is only copied to the VLAN
>>> when it is first created, resulting in an inconsistency after MAC
>>> address changes of only newly created VLANs having an up-to-date MAC.
>>>
>>> The VLANs should continue inheriting the MAC address of the physical
>>> interface, unless explicitly changed to be different from this.
>>> This allows IPv6 EUI64 addresses for the VLAN to reflect any changes
>>> to the MAC of the physical interface and thus for DAD to behave as
>>> expected.
>>>
>>> Signed-off-by: Mike Manning <mmanning@brocade.com>
>>> ---
>>> include/linux/if_vlan.h | 2 ++
>>> net/8021q/vlan.c | 17 +++++++++++------
>>> net/8021q/vlan_dev.c | 13 ++++++++++---
>>> 3 files changed, 23 insertions(+), 9 deletions(-)
>>>
>>> --- a/include/linux/if_vlan.h
>>> +++ b/include/linux/if_vlan.h
>>> @@ -138,6 +138,7 @@ struct netpoll;
>>> * @flags: device flags
>>> * @real_dev: underlying netdevice
>>> * @real_dev_addr: address of underlying netdevice
>>> + * @addr_assign_type: address assignment type
>>> * @dent: proc dir entry
>>> * @vlan_pcpu_stats: ptr to percpu rx stats
>>> */
>>> @@ -153,6 +154,7 @@ struct vlan_dev_priv {
>>>
>>> struct net_device *real_dev;
>>> unsigned char real_dev_addr[ETH_ALEN];
>>> + unsigned char addr_assign_type;
>>>
>>> struct proc_dir_entry *dent;
>>> struct vlan_pcpu_stats __percpu *vlan_pcpu_stats;
>>
>> Please don't start adding new members to structures when it already
>> exists in the net_device. If anything you should be able to drop
>> read_dev_addr if you do this correctly because you shouldn't need to
>> clone the lower dev address to watch for changes. All you will need
>> to do is watch NET_ADDR_STOLEN.
>>
>
> Thanks for the detailed review. I had initially used the existing type
> in net_device, but the problem with this was that it got overwritten to
> NET_ADDR_SET in dev_set_mac_address(), which I was reluctant to modify.
> It would just be a case of setting the type earlier in that function
> (and caching the previous value in case there is an error).
>
> However, based on your later comment, it seems I should not bother with
> the approach I have here, namely that if the VLAN MAC is set to the same
> value as that of the lower device MAC, that is to be considered as
> resetting it and thus for MAC inheritance to resume. Instead, I will just
> make this a 1-shot transition, i.e. the VLAN MAC starts off as inherited,
> and if it is set to anything (even the value of the lower device MAC),
> inheritance is stopped. I agree this makes for a far simpler changeset.
>
> I don't think I can remove real_dev_addr, as that is still needed for
> the existing functionality in vlan_sync_address() to determine if the sync
> should be done, also as a way of caching it for handling in vlan_dev_open().
The thing is that logic isn't really needed anymore though if you are
going to be following the lower dev. If you follow the code what it
is doing is adding the address via dev_uc_add if the lower address
moves away from the VLAN address. With your changes you are updating
the VLAN MAC address to the lower value in the NET_ADDR_STOLEN case so
you don't need to add or remove an extra unicast address. If the user
sets the MAC address you can then use the vlandev->dev_addr as the
address you add/remove from the unicast list and you probably don't
need to bother with tracking the lower device state anyway.
> As a matter of interest, what is the advantage of not updating the VLAN
> MAC when it is down? I appreciate that one should not add/delete
> secondary unicast addresses in this case, but there is no such
> restriction for copying the MAC.
Basically you are just wasting cycles messing with it while it is
down. You don't need to bother with syncing up the addresses until
you bring the interface up. At that point you essentially need to do
the vlan_sync_address type work anyway because you have to push your
address to the lower dev, or you have to pull it up from the lower dev
in the case of the stolen address. You don't want to have MAC
addresses written to the device for an interface that is down.
^ permalink raw reply
* Re: [RESEND PATCH 2/3] fs: poll/select/recvmmsg: use timespec64 for timeout events
From: David Miller @ 2016-05-06 19:45 UTC (permalink / raw)
To: john.stultz
Cc: eliezer.tamir, arnd, y2038, netdev, linux-kernel, oleg, arjan,
deepa.kernel, linux-fsdevel, akpm, torvalds, tglx, viro
In-Reply-To: <CALAqxLVPGBfuSmN_b_obAL5-ChfqpyipZtE-20x9omk_QeTQMw@mail.gmail.com>
From: John Stultz <john.stultz@linaro.org>
Date: Wed, 4 May 2016 17:01:24 -0700
> On Wed, May 4, 2016 at 4:51 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
>> On Wed, 04 May 2016 23:08:11 +0200 Arnd Bergmann <arnd@arndb.de> wrote:
>>
>>> > But I'm less comfortable making the call on this one. It looks
>>> > relatively straight forward, but it would be good to have maintainer
>>> > acks before I add it to my tree.
>>>
>>> Agreed. Feel free to add my
>>>
>>> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
>>>
>>> at least (whoever picks it up).
>>
>> In reply to [1/3] John said
>>
>> : Looks ok at the first glance. I've queued these up for testing,
>> : however I only got #1 and #3 of the set. Are you hoping these two
>> : patches will go through tip/timers/core or are you looking for acks so
>> : they can go via another tree?
>>
>> However none of the patches are in linux-next.
>>
>> John had qualms about [2/3], but it looks like a straightforward
>> substitution in areas which will get plenty of testing
>
> Yea. My main concern is just not stepping on any other maintainers toes.
The networking changes look fine to me:
Acked-by: David S. Miller <davem@davemloft.net>
_______________________________________________
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038
^ permalink raw reply
* Re: [PATCH net-next] cnic: call cp->stop_hw() in cnic_start_hw() on allocation failure
From: David Miller @ 2016-05-06 19:45 UTC (permalink / raw)
To: jmaxwell37; +Cc: netdev, linux-kernel, jmaxwell, ivecera
In-Reply-To: <1462406151-5224-1-git-send-email-jmaxwell37@gmail.com>
From: Jon Maxwell <jmaxwell37@gmail.com>
Date: Thu, 5 May 2016 09:55:51 +1000
> We recently had a system crash in the cnic module. Vmcore analysis confirmed
> that "ip link up" was executed which failed due to an allocation failure
> because of memory fragmentation. Futher analysis revealed that the cnic irq
> vector was still allocated after the "ip link up" that failed. When
> "ip link down" was executed it called free_msi_irqs() which crashed the system
> because the cnic irq was still inuse.
...
> The cnic_start_hw() routine is not handling the allocation failure correctly.
> Fix this by checking whether CNIC_DRV_STATE_HANDLES_IRQ flag is set indicating
> that the hardware has been started in cnic_start_hw(). If it has then call
> cp->stop_hw() which frees the cnic irq vector and cnic resources. Otherwise
> just maintain the previous behaviour and free cnic resources.
>
> I reproduced this by injecting an ENOMEM error into cnic_cm_alloc_mem()s return
> code.
>
> # ip link set dev enpX down
> # ip link set dev enpX up <--- hit's allocation failure
> # ip link set dev enpX down <--- crashes here
>
> With this patch I confirmed there was no crash in the reproducer.
>
> Signed-off-by: Jon Maxwell <jmaxwell37@gmail.com>
Applied, thank you.
^ permalink raw reply
* Re: OpenWRT wrong adjustment of fq_codel defaults (Was: fq_codel_drop vs a udp flood)
From: Dave Taht @ 2016-05-06 19:43 UTC (permalink / raw)
To: Roman Yeryomin
Cc: make-wifi-fast, Rafał Miłecki, ath10k,
netdev@vger.kernel.org, codel@lists.bufferbloat.net,
Jonathan Morton, OpenWrt Development List, Felix Fietkau
In-Reply-To: <CACiydb+A_vFNdp7tbw67Rnp+kHwt5GsLa+Su+pO8YmOZYp_KHg@mail.gmail.com>
On Fri, May 6, 2016 at 11:56 AM, Roman Yeryomin <leroi.lists@gmail.com> wrote:
> On 6 May 2016 at 21:43, Roman Yeryomin <leroi.lists@gmail.com> wrote:
>> On 6 May 2016 at 15:47, Jesper Dangaard Brouer <brouer@redhat.com> wrote:
>>>
>>> I've created a OpenWRT ticket[1] on this issue, as it seems that someone[2]
>>> closed Felix'es OpenWRT email account (bad choice! emails bouncing).
>>> Sounds like OpenWRT and the LEDE https://www.lede-project.org/ project
>>> is in some kind of conflict.
>>>
>>> OpenWRT ticket [1] https://dev.openwrt.org/ticket/22349
>>>
>>> [2] http://thread.gmane.org/gmane.comp.embedded.openwrt.devel/40298/focus=40335
>>
>> OK, so, after porting the patch to 4.1 openwrt kernel and playing a
>> bit with fq_codel limits I was able to get 420Mbps UDP like this:
>> tc qdisc replace dev wlan0 parent :1 fq_codel flows 16 limit 256
>
> Forgot to mention, I've reduced drop_batch_size down to 32
0) Not clear to me if that's the right line, there are 4 wifi queues,
and the third one
is the BE queue. That is too low a limit, also, for normal use. And:
for the purpose of this particular UDP test, flows 16 is ok, but not
ideal.
1) What's the tcp number (with a simultaneous ping) with this latest patchset?
(I care about tcp performance a lot more than udp floods - surviving a
udp flood yes, performance, no)
before/after?
tc -s qdisc show dev wlan0 during/after results?
IF you are doing builds for the archer c7v2, I can join in on this... (?)
I did do a test of the ath10k "before", fq_codel *never engaged*, and
tcp induced latencies under load, e at 100mbit, cracked 600ms, while
staying flat (20ms) at 100mbit. (not the same patches you are testing)
on x86. I have got tcp 300Mbit out of an osx box, similar latency,
have yet to get anything more on anything I currently have
before/after patchsets.
I'll go add flooding to the tests, I just finished a series comparing
two different speed stations and life was good on that.
"before" - fq_codel never engages, we see seconds of latency under load.
root@apu2:~# tc -s qdisc show dev wlp4s0
qdisc mq 0: root
Sent 8570563893 bytes 6326983 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc fq_codel 0: parent :1 limit 10240p flows 1024 quantum 1514
target 5.0ms interval 100.0ms ecn
Sent 2262 bytes 17 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
maxpacket 0 drop_overlimit 0 new_flow_count 0 ecn_mark 0
new_flows_len 0 old_flows_len 0
qdisc fq_codel 0: parent :2 limit 10240p flows 1024 quantum 1514
target 5.0ms interval 100.0ms ecn
Sent 220486569 bytes 152058 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
maxpacket 18168 drop_overlimit 0 new_flow_count 1 ecn_mark 0
new_flows_len 0 old_flows_len 1
qdisc fq_codel 0: parent :3 limit 10240p flows 1024 quantum 1514
target 5.0ms interval 100.0ms ecn
Sent 8340546509 bytes 6163431 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
maxpacket 68130 drop_overlimit 0 new_flow_count 120050 ecn_mark 0
new_flows_len 1 old_flows_len 3
qdisc fq_codel 0: parent :4 limit 10240p flows 1024 quantum 1514
target 5.0ms interval 100.0ms ecn
Sent 9528553 bytes 11477 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
maxpacket 66 drop_overlimit 0 new_flow_count 1 ecn_mark 0
new_flows_len 1 old_flows_len 0
```
>> This is certainly better than 30Mbps but still more than two times
>> less than before (900).
The number that I still am not sure we got is that you were sending
900mbit udp and recieving 900mbit on the prior tests?
>> TCP also improved a little (550 to ~590).
The limit is probably a bit low, also. You might want to try target
20ms as well.
>>
>> Felix, others, do you want to see the ported patch, maybe I did something wrong?
>> Doesn't look like it will save ath10k from performance regression.
what was tcp "before"? (I'm sorry, such a long thread)
>>
>>>
>>> On Fri, 6 May 2016 11:42:43 +0200
>>> Jesper Dangaard Brouer <brouer@redhat.com> wrote:
>>>
>>>> Hi Felix,
>>>>
>>>> This is an important fix for OpenWRT, please read!
>>>>
>>>> OpenWRT changed the default fq_codel sch->limit from 10240 to 1024,
>>>> without also adjusting q->flows_cnt. Eric explains below that you must
>>>> also adjust the buckets (q->flows_cnt) for this not to break. (Just
>>>> adjust it to 128)
>>>>
>>>> Problematic OpenWRT commit in question:
>>>> http://git.openwrt.org/?p=openwrt.git;a=patch;h=12cd6578084e
>>>> 12cd6578084e ("kernel: revert fq_codel quantum override to prevent it from causing too much cpu load with higher speed (#21326)")
>>>>
>>>>
>>>> I also highly recommend you cherry-pick this very recent commit:
>>>> net-next: 9d18562a2278 ("fq_codel: add batch ability to fq_codel_drop()")
>>>> https://git.kernel.org/davem/net-next/c/9d18562a227
>>>>
>>>> This should fix very high CPU usage in-case fq_codel goes into drop mode.
>>>> The problem is that drop mode was considered rare, and implementation
>>>> wise it was chosen to be more expensive (to save cycles on normal mode).
>>>> Unfortunately is it easy to trigger with an UDP flood. Drop mode is
>>>> especially expensive for smaller devices, as it scans a 4K big array,
>>>> thus 64 cache misses for small devices!
>>>>
>>>> The fix is to allow drop-mode to bulk-drop more packets when entering
>>>> drop-mode (default 64 bulk drop). That way we don't suddenly
>>>> experience a significantly higher processing cost per packet, but
>>>> instead can amortize this.
>>>>
>>>> To Eric, should we recommend OpenWRT to adjust default (max) 64 bulk
>>>> drop, given we also recommend bucket size to be 128 ? (thus the amount
>>>> of memory to scan is less, but their CPU is also much smaller).
>>>>
>>>> --Jesper
>>>>
>>>>
>>>> On Thu, 05 May 2016 12:23:27 -0700 Eric Dumazet <eric.dumazet@gmail.com> wrote:
>>>>
>>>> > On Thu, 2016-05-05 at 19:25 +0300, Roman Yeryomin wrote:
>>>> > > On 5 May 2016 at 19:12, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>>>> > > > On Thu, 2016-05-05 at 17:53 +0300, Roman Yeryomin wrote:
>>>> > > >
>>>> > > >>
>>>> > > >> qdisc fq_codel 0: dev eth0 root refcnt 2 limit 1024p flows 1024
>>>> > > >> quantum 1514 target 5.0ms interval 100.0ms ecn
>>>> > > >> Sent 12306 bytes 128 pkt (dropped 0, overlimits 0 requeues 0)
>>>> > > >> backlog 0b 0p requeues 0
>>>> > > >> maxpacket 0 drop_overlimit 0 new_flow_count 0 ecn_mark 0
>>>> > > >> new_flows_len 0 old_flows_len 0
>>>> > > >
>>>> > > >
>>>> > > > Limit of 1024 packets and 1024 flows is not wise I think.
>>>> > > >
>>>> > > > (If all buckets are in use, each bucket has a virtual queue of 1 packet,
>>>> > > > which is almost the same than having no queue at all)
>>>> > > >
>>>> > > > I suggest to have at least 8 packets per bucket, to let Codel have a
>>>> > > > chance to trigger.
>>>> > > >
>>>> > > > So you could either reduce number of buckets to 128 (if memory is
>>>> > > > tight), or increase limit to 8192.
>>>> > >
>>>> > > Will try, but what I've posted is default, I didn't change/configure that.
>>>> >
>>>> > fq_codel has a default of 10240 packets and 1024 buckets.
>>>> >
>>>> > http://lxr.free-electrons.com/source/net/sched/sch_fq_codel.c#L413
>>>> >
>>>> > If someone changed that in the linux variant you use, he probably should
>>>> > explain the rationale.
>>>
>>> --
>>> Best regards,
>>> Jesper Dangaard Brouer
>>> MSc.CS, Principal Kernel Engineer at Red Hat
>>> Author of http://www.iptv-analyzer.org
>>> LinkedIn: http://www.linkedin.com/in/brouer
--
Dave Täht
Let's go make home routers and wifi faster! With better software!
http://blog.cerowrt.org
_______________________________________________
Codel mailing list
Codel@lists.bufferbloat.net
https://lists.bufferbloat.net/listinfo/codel
^ permalink raw reply
* [PATCH] e1000e: prevent division by zero if TIMINCA is zero
From: Denys Vlasenko @ 2016-05-06 19:41 UTC (permalink / raw)
To: Jeff Kirsher
Cc: Denys Vlasenko, Ruinskiy, Dima, intel-wired-lan, netdev, LKML
Users report that under VMWare, er32(TIMINCA) returns zero.
This causes division by zero at init time as follows:
==> incvalue = er32(TIMINCA) & E1000_TIMINCA_INCVALUE_MASK;
for (i = 0; i < E1000_MAX_82574_SYSTIM_REREADS; i++) {
/* latch SYSTIMH on read of SYSTIML */
systim_next = (cycle_t)er32(SYSTIML);
systim_next |= (cycle_t)er32(SYSTIMH) << 32;
time_delta = systim_next - systim;
temp = time_delta;
====> rem = do_div(temp, incvalue);
This change makes kernel survive this, and users report that
NIC does work after this change.
Since on real hardware incvalue is never zero, this should not affect
real hardware use case.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: "Ruinskiy, Dima" <dima.ruinskiy@intel.com>
CC: intel-wired-lan@lists.osuosl.org
CC: netdev@vger.kernel.org
CC: LKML <linux-kernel@vger.kernel.org>
---
drivers/net/ethernet/intel/e1000e/netdev.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 269087c..0626935 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -4315,7 +4315,8 @@ static cycle_t e1000e_cyclecounter_read(const struct cyclecounter *cc)
time_delta = systim_next - systim;
temp = time_delta;
- rem = do_div(temp, incvalue);
+ /* VMWare users have seen incvalue of zero, don't div / 0 */
+ rem = incvalue ? do_div(temp, incvalue) : (time_delta != 0);
systim = systim_next;
--
1.8.1.4
^ permalink raw reply related
* Re: [PATCH net] netfilter: nf_conntrack: Use net_mutex for helper unregistration.
From: Joe Stringer @ 2016-05-06 19:38 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netdev, netfilter-devel, Florian Westphal
In-Reply-To: <20160506110325.GA2420@salvia>
On 6 May 2016 at 04:03, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> Hi Joe,
>
> On Thu, May 05, 2016 at 03:50:37PM -0700, Joe Stringer wrote:
>> diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
>> index 3b40ec575cd5..6860b19be406 100644
>> --- a/net/netfilter/nf_conntrack_helper.c
>> +++ b/net/netfilter/nf_conntrack_helper.c
>> @@ -449,10 +449,10 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
>> */
>> synchronize_rcu();
>>
>> - rtnl_lock();
>> + mutex_lock(&net_mutex);
>> for_each_net(net)
>> __nf_conntrack_helper_unregister(me, net);
>> - rtnl_unlock();
>> + mutex_unlock(&net_mutex);
>
> This simple solution works because we have no .exit callbacks in any
> of our helpers. Otherwise, the helper code may be already gone by when
> the worker has a chance to run to release the netns.
I'm open to any alternative solutions, but if helper code isn't doing
this yet then perhaps this fix is sufficient?
> If so, probably I can append this as comment to this function so we
> don't forget. If we ever have .exit callbacks (I don't expect so), we
> would need to wait for worker completion.
Sounds reasonable to me.
I see there's a bunch of other unregister locations like
nf_nat_l3proto_clean(), nf_nat_l4proto_clean(), nf_unregister_hook()
which might need similar treatment?
^ 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