* [PATCH v5 net-next 11/12] gtp: Experimental support encpasulating over IPv6
From: Tom Herbert @ 2017-10-18 20:10 UTC (permalink / raw)
To: davem; +Cc: pablo, laforge, aschultz, netdev, rohit, Tom Herbert
In-Reply-To: <20171018201018.5692-1-tom@quantonium.net>
Allows using GTP datapath over IPv6. Remote peers are indicated by IPv6.
Note this is experimental, more work is needed to make this
compliant with 3GPP standard.
Signed-off-by: Tom Herbert <tom@quantonium.net>
---
drivers/net/gtp.c | 248 ++++++++++++++++++++++++++++++++++---------
include/uapi/linux/gtp.h | 1 +
include/uapi/linux/if_link.h | 3 +
3 files changed, 200 insertions(+), 52 deletions(-)
diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 919ec6e14973..1c580df4cfc5 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -28,6 +28,7 @@
#include <net/net_namespace.h>
#include <net/protocol.h>
#include <net/ip.h>
+#include <net/ip6_tunnel.h>
#include <net/udp.h>
#include <net/udp_tunnel.h>
#include <net/icmp.h>
@@ -59,16 +60,22 @@ struct pdp_ctx {
__be16 gtp_port;
u16 ms_af;
+ u16 peer_af;
#if GTP_IPV6
union {
struct in_addr ms_addr_ip4;
struct in6_addr ms_addr_ip6;
};
+
+ union {
+ struct in_addr peer_addr_ip4;
+ struct in6_addr peer_addr_ip6;
+ };
#else
struct in_addr ms_addr_ip4;
+ struct in_addr peer_addr_ip4;
#endif
- struct in_addr peer_addr_ip4;
struct sock *sk;
struct net_device *dev;
@@ -93,8 +100,11 @@ struct gtp_dev {
struct hlist_head *tid_hash;
struct hlist_head *addr4_hash;
+
#if GTP_IPV6
struct hlist_head *addr6_hash;
+
+ unsigned int is_ipv6:1;
#endif
struct gro_cells gro_cells;
@@ -534,8 +544,6 @@ static int gtp_xmit(struct sk_buff *skb, struct net_device *dev,
{
struct iphdr *inner_iph = NULL;
struct sock *sk = pctx->sk;
- __be32 saddr = inet_sk(sk)->inet_saddr;
- struct rtable *rt;
int err = 0;
if (skb->protocol == ETH_P_IP)
@@ -548,38 +556,84 @@ static int gtp_xmit(struct sk_buff *skb, struct net_device *dev,
skb_reset_inner_headers(skb);
- /* Source address returned by route lookup is ignored since
- * we get the address from a socket.
- */
- rt = ip_tunnel_get_route(dev, skb, sk->sk_protocol,
- sk->sk_bound_dev_if, RT_CONN_FLAGS(sk),
- pctx->peer_addr_ip4.s_addr, &saddr,
- pctx->gtp_port, pctx->gtp_port,
- &pctx->dst_cache, NULL);
-
- if (IS_ERR(rt)) {
- err = PTR_ERR(rt);
- goto out_err;
- }
+ if (pctx->peer_af == AF_INET) {
+ __be32 saddr = inet_sk(sk)->inet_saddr;
+ struct rtable *rt;
+
+ /* Source address returned by route lookup is ignored since
+ * we get the address from a socket.
+ */
+ rt = ip_tunnel_get_route(dev, skb, sk->sk_protocol,
+ sk->sk_bound_dev_if, RT_CONN_FLAGS(sk),
+ pctx->peer_addr_ip4.s_addr, &saddr,
+ pctx->gtp_port, pctx->gtp_port,
+ &pctx->dst_cache, NULL);
+
+ if (IS_ERR(rt)) {
+ err = PTR_ERR(rt);
+ goto out_err;
+ }
+
+ skb_dst_drop(skb);
- skb_dst_drop(skb);
+ gtp_push_header(skb, pctx);
- gtp_push_header(skb, pctx);
+ if (inner_iph)
+ __iptunnel_update_pmtu(dev, skb, &rt->dst,
+ !!inner_iph->frag_off,
+ inner_iph, pctx->hlen,
+ pctx->peer_addr_ip4.s_addr);
- if (inner_iph)
- __iptunnel_update_pmtu(dev, skb, &rt->dst,
- !!inner_iph->frag_off,
- inner_iph, pctx->hlen,
- pctx->peer_addr_ip4.s_addr);
+ udp_tunnel_xmit_skb(rt, sk, skb, saddr,
+ pctx->peer_addr_ip4.s_addr,
+ 0, ip4_dst_hoplimit(&rt->dst), 0,
+ pctx->gtp_port, pctx->gtp_port,
+ false, false);
- udp_tunnel_xmit_skb(rt, sk, skb, saddr,
- pctx->peer_addr_ip4.s_addr,
- 0, ip4_dst_hoplimit(&rt->dst), 0,
- pctx->gtp_port, pctx->gtp_port,
- false, false);
+ netdev_dbg(dev, "gtp -> IP src: %pI4 dst: %pI4\n",
+ &saddr, &pctx->peer_addr_ip4.s_addr);
- netdev_dbg(dev, "gtp -> IP src: %pI4 dst: %pI4\n",
- &saddr, &pctx->peer_addr_ip4.s_addr);
+#if GTP_IPV6
+#if IS_ENABLED(CONFIG_IPV6)
+ } else if (pctx->peer_af == AF_INET6) {
+ struct in6_addr saddr = inet6_sk(sk)->saddr;
+ struct dst_entry *dst;
+
+ /* Source address returned by route lookup is ignored since
+ * we get the address from a socket.
+ */
+ dst = ip6_tnl_get_route(dev, skb, sk, sk->sk_protocol,
+ sk->sk_bound_dev_if, 0,
+ 0, &pctx->peer_addr_ip6, &saddr,
+ pctx->gtp_port, pctx->gtp_port,
+ &pctx->dst_cache, NULL);
+
+ if (IS_ERR(dst)) {
+ err = PTR_ERR(dst);
+ goto out_err;
+ }
+
+ skb_dst_drop(skb);
+
+ gtp_push_header(skb, pctx);
+
+ if (inner_iph)
+ __iptunnel_update_pmtu(dev, skb, dst,
+ !!inner_iph->frag_off,
+ inner_iph, pctx->hlen, 0);
+
+ udp_tunnel6_xmit_skb(dst, sk, skb, dev,
+ &saddr, &pctx->peer_addr_ip6,
+ 0, ip6_dst_hoplimit(dst), 0,
+ pctx->gtp_port, pctx->gtp_port,
+ false);
+
+ netdev_dbg(dev, "gtp -> IP src: %pI6 dst: %pI6\n",
+ &saddr, &pctx->peer_addr_ip6);
+
+#endif
+#endif
+ }
return 0;
@@ -688,7 +742,12 @@ static void gtp_link_setup(struct net_device *dev)
/* Assume largest header, ie. GTPv0. */
dev->needed_headroom = LL_MAX_HEADER +
+#if GTP_IPV6
+ max_t(int, sizeof(struct iphdr),
+ sizeof(struct ipv6hdr)) +
+#else
sizeof(struct iphdr) +
+#endif
sizeof(struct udphdr) +
sizeof(struct gtp0_header);
@@ -697,12 +756,15 @@ static void gtp_link_setup(struct net_device *dev)
static int gtp_hashtable_new(struct gtp_dev *gtp, int hsize);
static void gtp_hashtable_free(struct gtp_dev *gtp);
-static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[]);
+static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[],
+ bool is_ipv6);
static int gtp_newlink(struct net *src_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
{
+ unsigned int role = GTP_ROLE_GGSN;
+ bool is_ipv6 = false;
struct gtp_dev *gtp;
struct gtp_net *gn;
int hashsize, err;
@@ -710,9 +772,32 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
if (!data[IFLA_GTP_FD0] && !data[IFLA_GTP_FD1])
return -EINVAL;
+ if (data[IFLA_GTP_ROLE]) {
+ role = nla_get_u32(data[IFLA_GTP_ROLE]);
+ if (role > GTP_ROLE_SGSN)
+ return -EINVAL;
+ }
+
+ if (data[IFLA_GTP_AF]) {
+ u16 af = nla_get_u16(data[IFLA_GTP_AF]);
+
+ switch (af) {
+ case AF_INET:
+ is_ipv6 = false;
+ break;
+#if GTP_IPV6
+ case AF_INET6:
+ is_ipv6 = true;
+ break;
+#endif
+ default:
+ return -EINVAL;
+ }
+ }
+
gtp = netdev_priv(dev);
- err = gtp_encap_enable(gtp, data);
+ err = gtp_encap_enable(gtp, data, is_ipv6);
if (err < 0)
return err;
@@ -731,6 +816,11 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
goto out_hashtable;
}
+ gtp->role = role;
+#if GTP_IPV6
+ gtp->is_ipv6 = is_ipv6;
+#endif
+
gn = net_generic(dev_net(dev), gtp_net_id);
list_add_rcu(>p->list, &gn->gtp_dev_list);
@@ -860,7 +950,8 @@ static void gtp_hashtable_free(struct gtp_dev *gtp)
}
static struct sock *gtp_encap_enable_socket(int fd, int type,
- struct gtp_dev *gtp)
+ struct gtp_dev *gtp,
+ bool is_ipv6)
{
struct udp_tunnel_sock_cfg tuncfg = {NULL};
struct socket *sock;
@@ -881,6 +972,12 @@ static struct sock *gtp_encap_enable_socket(int fd, int type,
goto out_sock;
}
+ if (sock->sk->sk_family != (is_ipv6 ? AF_INET6 : AF_INET)) {
+ pr_debug("socket fd=%d not right family\n", fd);
+ sk = ERR_PTR(-EINVAL);
+ goto out_sock;
+ }
+
if (rcu_dereference_sk_user_data(sock->sk)) {
sk = ERR_PTR(-EBUSY);
goto out_sock;
@@ -913,16 +1010,16 @@ static struct sock *gtp_encap_enable_socket(int fd, int type,
return sk;
}
-static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[])
+static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[],
+ bool is_ipv6)
{
- struct sock *sk1u = NULL;
- struct sock *sk0 = NULL;
- unsigned int role = GTP_ROLE_GGSN;
+ struct sock *sk0 = NULL, *sk1u = NULL;
if (data[IFLA_GTP_FD0]) {
u32 fd0 = nla_get_u32(data[IFLA_GTP_FD0]);
- sk0 = gtp_encap_enable_socket(fd0, UDP_ENCAP_GTP0, gtp);
+ sk0 = gtp_encap_enable_socket(fd0, UDP_ENCAP_GTP0, gtp,
+ is_ipv6);
if (IS_ERR(sk0))
return PTR_ERR(sk0);
}
@@ -930,7 +1027,8 @@ static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[])
if (data[IFLA_GTP_FD1]) {
u32 fd1 = nla_get_u32(data[IFLA_GTP_FD1]);
- sk1u = gtp_encap_enable_socket(fd1, UDP_ENCAP_GTP1U, gtp);
+ sk1u = gtp_encap_enable_socket(fd1, UDP_ENCAP_GTP1U, gtp,
+ is_ipv6);
if (IS_ERR(sk1u)) {
if (sk0)
gtp_encap_disable_sock(sk0);
@@ -938,15 +1036,8 @@ static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[])
}
}
- if (data[IFLA_GTP_ROLE]) {
- role = nla_get_u32(data[IFLA_GTP_ROLE]);
- if (role > GTP_ROLE_SGSN)
- return -EINVAL;
- }
-
gtp->sk0 = sk0;
gtp->sk1u = sk1u;
- gtp->role = role;
return 0;
}
@@ -982,8 +1073,18 @@ static void pdp_fill(struct pdp_ctx *pctx, struct genl_info *info)
__be16 default_port = 0;
pctx->gtp_version = nla_get_u32(info->attrs[GTPA_VERSION]);
- pctx->peer_addr_ip4.s_addr =
- nla_get_be32(info->attrs[GTPA_PEER_ADDRESS]);
+
+ if (info->attrs[GTPA_PEER_ADDRESS]) {
+ pctx->peer_af = AF_INET;
+ pctx->peer_addr_ip4.s_addr =
+ nla_get_in_addr(info->attrs[GTPA_PEER_ADDRESS]);
+#if GTP_IPV6
+ } else if (info->attrs[GTPA_PEER6_ADDRESS]) {
+ pctx->peer_af = AF_INET6;
+ pctx->peer_addr_ip6 = nla_get_in6_addr(
+ info->attrs[GTPA_PEER6_ADDRESS]);
+#endif
+ }
switch (pctx->gtp_version) {
case GTP_V0:
@@ -1162,11 +1263,17 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info)
int err;
if (!info->attrs[GTPA_VERSION] ||
- !info->attrs[GTPA_LINK] ||
- !info->attrs[GTPA_PEER_ADDRESS])
+ !info->attrs[GTPA_LINK])
return -EINVAL;
#if GTP_IPV6
+ if (!(!!info->attrs[GTPA_PEER_ADDRESS] ^
+ !!info->attrs[GTPA_PEER6_ADDRESS])) {
+ /* Either v4 or v6 peer address must be set */
+
+ return -EINVAL;
+ }
+
if (!(!!info->attrs[GTPA_MS_ADDRESS] ^
!!info->attrs[GTPA_MS6_ADDRESS])) {
/* Either v4 or v6 mobile subscriber address must be set */
@@ -1174,6 +1281,12 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info)
return -EINVAL;
}
#else
+ if (!info->attrs[GTPA_PEER_ADDRESS]) {
+ /* v4 peer address must be set */
+
+ return -EINVAL;
+ }
+
if (!info->attrs[GTPA_MS_ADDRESS]) {
/* v4 mobile subscriber address must be set */
@@ -1207,6 +1320,14 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info)
goto out_unlock;
}
+#if GTP_IPV6
+ if ((info->attrs[GTPA_PEER_ADDRESS] && gtp->is_ipv6) ||
+ (info->attrs[GTPA_PEER6_ADDRESS] && !gtp->is_ipv6)) {
+ err = -EINVAL;
+ goto out_unlock;
+ }
+#endif
+
if (version == GTP_V0)
sk = gtp->sk0;
else if (version == GTP_V1)
@@ -1315,10 +1436,31 @@ static int gtp_genl_fill_info(struct sk_buff *skb, u32 snd_portid, u32 snd_seq,
if (genlh == NULL)
goto nlmsg_failure;
- if (nla_put_u32(skb, GTPA_VERSION, pctx->gtp_version) ||
- nla_put_be32(skb, GTPA_PEER_ADDRESS, pctx->peer_addr_ip4.s_addr))
+ if (nla_put_u32(skb, GTPA_VERSION, pctx->gtp_version))
goto nla_put_failure;
+ if (nla_put_u32(skb, GTPA_LINK, pctx->dev->ifindex))
+ goto nla_put_failure;
+
+ switch (pctx->peer_af) {
+ case AF_INET:
+ if (nla_put_be32(skb, GTPA_PEER_ADDRESS,
+ pctx->peer_addr_ip4.s_addr))
+ goto nla_put_failure;
+
+ break;
+#if GTP_IPV6
+ case AF_INET6:
+ if (nla_put_in6_addr(skb, GTPA_PEER6_ADDRESS,
+ &pctx->peer_addr_ip6))
+ goto nla_put_failure;
+
+ break;
+#endif
+ default:
+ goto nla_put_failure;
+ }
+
switch (pctx->ms_af) {
case AF_INET:
if (nla_put_be32(skb, GTPA_MS_ADDRESS,
@@ -1448,6 +1590,8 @@ static struct nla_policy gtp_genl_policy[GTPA_MAX + 1] = {
[GTPA_PEER_ADDRESS] = { .type = NLA_U32, },
[GTPA_MS_ADDRESS] = { .type = NLA_U32, },
#if GTP_IPV6
+ [GTPA_PEER6_ADDRESS] = { .len = FIELD_SIZEOF(struct ipv6hdr,
+ daddr) },
[GTPA_MS6_ADDRESS] = { .len = FIELD_SIZEOF(struct ipv6hdr,
daddr) },
#endif
diff --git a/include/uapi/linux/gtp.h b/include/uapi/linux/gtp.h
index ae4e632c0360..8eec519fa754 100644
--- a/include/uapi/linux/gtp.h
+++ b/include/uapi/linux/gtp.h
@@ -29,6 +29,7 @@ enum gtp_attrs {
GTPA_PAD,
GTPA_PORT,
GTPA_MS6_ADDRESS,
+ GTPA_PEER6_ADDRESS,
__GTPA_MAX,
};
#define GTPA_MAX (__GTPA_MAX + 1)
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index b037e0ab1975..1abf0f5c01fc 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -555,6 +555,9 @@ enum {
IFLA_GTP_FD1,
IFLA_GTP_PDP_HASHSIZE,
IFLA_GTP_ROLE,
+ IFLA_GTP_AF,
+ IFLA_GTP_PORT0,
+ IFLA_GTP_PORT1,
__IFLA_GTP_MAX,
};
#define IFLA_GTP_MAX (__IFLA_GTP_MAX - 1)
--
2.11.0
^ permalink raw reply related
* [PATCH v5 net-next 12/12] gtp: Allow configuring GTP interface as standalone
From: Tom Herbert @ 2017-10-18 20:10 UTC (permalink / raw)
To: davem; +Cc: pablo, laforge, aschultz, netdev, rohit, Tom Herbert
In-Reply-To: <20171018201018.5692-1-tom@quantonium.net>
Add new configuration of GTP interfaces that allow specifying a port to
listen on (as opposed to having to get sockets from a userspace control
plane). This allows GTP interfaces to be configured and the data path
tested without requiring a GTP-C daemon.
Signed-off-by: Tom Herbert <tom@quantonium.net>
---
drivers/net/gtp.c | 215 ++++++++++++++++++++++++++++++++++++-----------
include/uapi/linux/gtp.h | 5 ++
2 files changed, 169 insertions(+), 51 deletions(-)
diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 1c580df4cfc5..dc1fcd3034af 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -93,6 +93,9 @@ struct gtp_dev {
struct sock *sk0;
struct sock *sk1u;
+ struct socket *sock0;
+ struct socket *sock1u;
+
struct net_device *dev;
unsigned int role;
@@ -451,26 +454,33 @@ static void gtp_encap_destroy(struct sock *sk)
}
}
-static void gtp_encap_disable_sock(struct sock *sk)
+static void gtp_encap_release(struct gtp_dev *gtp)
{
- if (!sk)
- return;
+ if (gtp->sk0) {
+ if (gtp->sock0) {
+ udp_tunnel_sock_release(gtp->sock0);
+ gtp->sock0 = NULL;
+ } else {
+ gtp_encap_destroy(gtp->sk0);
+ }
- gtp_encap_destroy(sk);
-}
+ gtp->sk0 = NULL;
+ }
-static void gtp_encap_disable(struct gtp_dev *gtp)
-{
- gtp_encap_disable_sock(gtp->sk0);
- gtp_encap_disable_sock(gtp->sk1u);
+ if (gtp->sk1u) {
+ if (gtp->sock1u) {
+ udp_tunnel_sock_release(gtp->sock1u);
+ gtp->sock1u = NULL;
+ } else {
+ gtp_encap_destroy(gtp->sk1u);
+ }
+
+ gtp->sk1u = NULL;
+ }
}
static int gtp_dev_init(struct net_device *dev)
{
- struct gtp_dev *gtp = netdev_priv(dev);
-
- gtp->dev = dev;
-
dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
if (!dev->tstats)
return -ENOMEM;
@@ -482,7 +492,8 @@ static void gtp_dev_uninit(struct net_device *dev)
{
struct gtp_dev *gtp = netdev_priv(dev);
- gtp_encap_disable(gtp);
+ gtp_encap_release(gtp);
+
free_percpu(dev->tstats);
}
@@ -751,6 +762,8 @@ static void gtp_link_setup(struct net_device *dev)
sizeof(struct udphdr) +
sizeof(struct gtp0_header);
+ gtp->dev = dev;
+
gro_cells_init(>p->gro_cells, dev);
}
@@ -764,13 +777,19 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
struct netlink_ext_ack *extack)
{
unsigned int role = GTP_ROLE_GGSN;
+ bool have_fd, have_ports;
bool is_ipv6 = false;
struct gtp_dev *gtp;
struct gtp_net *gn;
int hashsize, err;
- if (!data[IFLA_GTP_FD0] && !data[IFLA_GTP_FD1])
+ have_fd = !!data[IFLA_GTP_FD0] || !!data[IFLA_GTP_FD1];
+ have_ports = !!data[IFLA_GTP_PORT0] || !!data[IFLA_GTP_PORT1];
+
+ if (!(have_fd ^ have_ports)) {
+ /* Either got fd(s) or port(s) */
return -EINVAL;
+ }
if (data[IFLA_GTP_ROLE]) {
role = nla_get_u32(data[IFLA_GTP_ROLE]);
@@ -831,7 +850,7 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
out_hashtable:
gtp_hashtable_free(gtp);
out_encap:
- gtp_encap_disable(gtp);
+ gtp_encap_release(gtp);
return err;
}
@@ -840,7 +859,7 @@ static void gtp_dellink(struct net_device *dev, struct list_head *head)
struct gtp_dev *gtp = netdev_priv(dev);
gro_cells_destroy(>p->gro_cells);
- gtp_encap_disable(gtp);
+ gtp_encap_release(gtp);
gtp_hashtable_free(gtp);
list_del_rcu(>p->list);
unregister_netdevice_queue(dev, head);
@@ -851,6 +870,8 @@ static const struct nla_policy gtp_policy[IFLA_GTP_MAX + 1] = {
[IFLA_GTP_FD1] = { .type = NLA_U32 },
[IFLA_GTP_PDP_HASHSIZE] = { .type = NLA_U32 },
[IFLA_GTP_ROLE] = { .type = NLA_U32 },
+ [IFLA_GTP_PORT0] = { .type = NLA_U16 },
+ [IFLA_GTP_PORT1] = { .type = NLA_U16 },
};
static int gtp_validate(struct nlattr *tb[], struct nlattr *data[],
@@ -949,11 +970,35 @@ static void gtp_hashtable_free(struct gtp_dev *gtp)
kfree(gtp->tid_hash);
}
-static struct sock *gtp_encap_enable_socket(int fd, int type,
- struct gtp_dev *gtp,
- bool is_ipv6)
+static int gtp_encap_enable_sock(struct socket *sock, int type,
+ struct gtp_dev *gtp)
{
struct udp_tunnel_sock_cfg tuncfg = {NULL};
+
+ switch (type) {
+ case UDP_ENCAP_GTP0:
+ tuncfg.encap_rcv = gtp0_udp_encap_recv;
+ break;
+ case UDP_ENCAP_GTP1U:
+ tuncfg.encap_rcv = gtp1u_udp_encap_recv;
+ break;
+ default:
+ pr_debug("Unknown encap type %u\n", type);
+ return -EINVAL;
+ }
+
+ tuncfg.sk_user_data = gtp;
+ tuncfg.encap_type = type;
+ tuncfg.encap_destroy = gtp_encap_destroy;
+
+ setup_udp_tunnel_sock(sock_net(sock->sk), sock, &tuncfg);
+
+ return 0;
+}
+
+static struct sock *gtp_encap_enable_fd(int fd, int type, struct gtp_dev *gtp,
+ bool is_ipv6)
+{
struct socket *sock;
struct sock *sk;
int err;
@@ -986,60 +1031,128 @@ static struct sock *gtp_encap_enable_socket(int fd, int type,
sk = sock->sk;
sock_hold(sk);
- switch (type) {
- case UDP_ENCAP_GTP0:
- tuncfg.encap_rcv = gtp0_udp_encap_recv;
- break;
- case UDP_ENCAP_GTP1U:
- tuncfg.encap_rcv = gtp1u_udp_encap_recv;
- break;
- default:
- pr_debug("Unknown encap type %u\n", type);
- sk = ERR_PTR(-EINVAL);
- goto out_sock;
- }
-
- tuncfg.sk_user_data = gtp;
- tuncfg.encap_type = type;
- tuncfg.encap_destroy = gtp_encap_destroy;
-
- setup_udp_tunnel_sock(sock_net(sock->sk), sock, &tuncfg);
+ err = gtp_encap_enable_sock(sock, type, gtp);
+ if (err < 0)
+ sk = ERR_PTR(err);
out_sock:
sockfd_put(sock);
return sk;
}
+static struct socket *gtp_create_sock(struct net *net, bool ipv6,
+ __be16 port, u32 flags)
+{
+ struct socket *sock;
+ struct udp_port_cfg udp_conf;
+ int err;
+
+ memset(&udp_conf, 0, sizeof(udp_conf));
+
+#if GTP_IPV6
+ if (ipv6) {
+ udp_conf.family = AF_INET6;
+ udp_conf.ipv6_v6only = 1;
+ } else {
+ udp_conf.family = AF_INET;
+ }
+#else
+ udp_conf.family = AF_INET;
+#endif
+
+ udp_conf.local_udp_port = port;
+
+ /* Open UDP socket */
+ err = udp_sock_create(net, &udp_conf, &sock);
+ if (err)
+ return ERR_PTR(err);
+
+ return sock;
+}
+
static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[],
bool is_ipv6)
{
+ int err;
+
+ struct socket *sock0 = NULL, *sock1u = NULL;
struct sock *sk0 = NULL, *sk1u = NULL;
if (data[IFLA_GTP_FD0]) {
u32 fd0 = nla_get_u32(data[IFLA_GTP_FD0]);
- sk0 = gtp_encap_enable_socket(fd0, UDP_ENCAP_GTP0, gtp,
- is_ipv6);
- if (IS_ERR(sk0))
- return PTR_ERR(sk0);
+ sk0 = gtp_encap_enable_fd(fd0, UDP_ENCAP_GTP0, gtp, is_ipv6);
+ if (IS_ERR(sk0)) {
+ err = PTR_ERR(sk0);
+ sk0 = NULL;
+ goto out_err;
+ }
+ } else if (data[IFLA_GTP_PORT0]) {
+ __be16 port = nla_get_u16(data[IFLA_GTP_PORT0]);
+
+ sock0 = gtp_create_sock(dev_net(gtp->dev), is_ipv6, port, 0);
+ if (IS_ERR(sock0)) {
+ err = PTR_ERR(sock0);
+ sock0 = NULL;
+ goto out_err;
+ }
+
+ err = gtp_encap_enable_sock(sock0, UDP_ENCAP_GTP0, gtp);
+ if (err)
+ goto out_err;
}
if (data[IFLA_GTP_FD1]) {
u32 fd1 = nla_get_u32(data[IFLA_GTP_FD1]);
- sk1u = gtp_encap_enable_socket(fd1, UDP_ENCAP_GTP1U, gtp,
- is_ipv6);
+ sk1u = gtp_encap_enable_fd(fd1, UDP_ENCAP_GTP1U, gtp, is_ipv6);
if (IS_ERR(sk1u)) {
- if (sk0)
- gtp_encap_disable_sock(sk0);
- return PTR_ERR(sk1u);
+ err = PTR_ERR(sk1u);
+ sk1u = NULL;
+ goto out_err;
+ }
+ } else if (data[IFLA_GTP_PORT1]) {
+ __be16 port = nla_get_u16(data[IFLA_GTP_PORT1]);
+
+ sock1u = gtp_create_sock(dev_net(gtp->dev), is_ipv6, port, 0);
+ if (IS_ERR(sock1u)) {
+ err = PTR_ERR(sock1u);
+ sock1u = NULL;
+ goto out_err;
}
+
+ err = gtp_encap_enable_sock(sock1u, UDP_ENCAP_GTP1U, gtp);
+ if (err)
+ goto out_err;
+ }
+
+ if (sock0) {
+ gtp->sock0 = sock0;
+ gtp->sk0 = sock0->sk;
+ } else {
+ gtp->sk0 = sk0;
}
- gtp->sk0 = sk0;
- gtp->sk1u = sk1u;
+ if (sock1u) {
+ gtp->sock1u = sock1u;
+ gtp->sk1u = sock1u->sk;
+ } else {
+ gtp->sk1u = sk1u;
+ }
return 0;
+
+out_err:
+ if (sk0)
+ gtp_encap_destroy(sk0);
+ if (sk1u)
+ gtp_encap_destroy(sk1u);
+ if (sock0)
+ udp_tunnel_sock_release(sock0);
+ if (sock1u)
+ udp_tunnel_sock_release(sock1u);
+
+ return err;
}
static struct gtp_dev *gtp_find_dev(struct net *src_net, struct nlattr *nla[])
@@ -1624,8 +1737,8 @@ static const struct genl_ops gtp_genl_ops[] = {
};
static struct genl_family gtp_genl_family __ro_after_init = {
- .name = "gtp",
- .version = 0,
+ .name = GTP_GENL_NAME,
+ .version = GTP_GENL_VERSION,
.hdrsize = 0,
.maxattr = GTPA_MAX,
.netnsok = true,
diff --git a/include/uapi/linux/gtp.h b/include/uapi/linux/gtp.h
index 8eec519fa754..0da18aa88be8 100644
--- a/include/uapi/linux/gtp.h
+++ b/include/uapi/linux/gtp.h
@@ -9,6 +9,11 @@ enum gtp_genl_cmds {
GTP_CMD_MAX,
};
+/* NETLINK_GENERIC related info
+ */
+#define GTP_GENL_NAME "gtp"
+#define GTP_GENL_VERSION 0
+
enum gtp_version {
GTP_V0 = 0,
GTP_V1,
--
2.11.0
^ permalink raw reply related
* Re: [PATCH net-next] tcp: socket option to set TCP fast open key
From: Christoph Paasch @ 2017-10-18 20:13 UTC (permalink / raw)
To: Yuchung Cheng; +Cc: davem, netdev, edumazet, ncardwell, maheshb
In-Reply-To: <20171018182251.5486-1-ycheng@google.com>
Hello Yuchung,
On 18/10/17 - 11:22:51, Yuchung Cheng wrote:
> New socket option TCP_FASTOPEN_KEY to allow different keys per
> listener. The listener by default uses the global key until the
> socket option is set. The key is a 16 bytes long binary data. This
> option has no effect on regular non-listener TCP sockets.
can you explain what the use-case is to have per-listener TFO keys?
Thanks,
Christoph
>
> Signed-off-by: Yuchung Cheng <ycheng@google.com>
> Reviewed-by: Eric Dumazet <edumazet@google.com>
> ---
> include/net/request_sock.h | 2 ++
> include/net/tcp.h | 5 +++--
> include/uapi/linux/tcp.h | 1 +
> net/ipv4/sysctl_net_ipv4.c | 3 ++-
> net/ipv4/tcp.c | 33 +++++++++++++++++++++++++++
> net/ipv4/tcp_fastopen.c | 56 +++++++++++++++++++++++++++++++++-------------
> net/ipv4/tcp_ipv4.c | 1 +
> 7 files changed, 82 insertions(+), 19 deletions(-)
>
> diff --git a/include/net/request_sock.h b/include/net/request_sock.h
> index 23e22054aa60..347015515a7d 100644
> --- a/include/net/request_sock.h
> +++ b/include/net/request_sock.h
> @@ -150,6 +150,8 @@ struct fastopen_queue {
> spinlock_t lock;
> int qlen; /* # of pending (TCP_SYN_RECV) reqs */
> int max_qlen; /* != 0 iff TFO is currently enabled */
> +
> + struct tcp_fastopen_context __rcu *ctx; /* cipher context for cookie */
> };
>
> /** struct request_sock_queue - queue of request_socks
> diff --git a/include/net/tcp.h b/include/net/tcp.h
> index 3b3b9b968e2d..1efe8365cb28 100644
> --- a/include/net/tcp.h
> +++ b/include/net/tcp.h
> @@ -1555,9 +1555,10 @@ struct tcp_fastopen_request {
> int copied; /* queued in tcp_connect() */
> };
> void tcp_free_fastopen_req(struct tcp_sock *tp);
> -
> +void tcp_fastopen_destroy_cipher(struct sock *sk);
> void tcp_fastopen_ctx_destroy(struct net *net);
> -int tcp_fastopen_reset_cipher(struct net *net, void *key, unsigned int len);
> +int tcp_fastopen_reset_cipher(struct net *net, struct sock *sk,
> + void *key, unsigned int len);
> void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb);
> struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
> struct request_sock *req,
> diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h
> index 15c25eccab2b..69c7493e42f8 100644
> --- a/include/uapi/linux/tcp.h
> +++ b/include/uapi/linux/tcp.h
> @@ -119,6 +119,7 @@ enum {
> #define TCP_FASTOPEN_CONNECT 30 /* Attempt FastOpen with connect */
> #define TCP_ULP 31 /* Attach a ULP to a TCP connection */
> #define TCP_MD5SIG_EXT 32 /* TCP MD5 Signature with extensions */
> +#define TCP_FASTOPEN_KEY 33 /* Set the key for Fast Open (cookie) */
>
> struct tcp_repair_opt {
> __u32 opt_code;
> diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
> index cac8dd309f39..81d218346cf7 100644
> --- a/net/ipv4/sysctl_net_ipv4.c
> +++ b/net/ipv4/sysctl_net_ipv4.c
> @@ -284,7 +284,8 @@ static int proc_tcp_fastopen_key(struct ctl_table *table, int write,
> ret = -EINVAL;
> goto bad_key;
> }
> - tcp_fastopen_reset_cipher(net, user_key, TCP_FASTOPEN_KEY_LENGTH);
> + tcp_fastopen_reset_cipher(net, NULL, user_key,
> + TCP_FASTOPEN_KEY_LENGTH);
> }
>
> bad_key:
> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> index 3b34850d361f..8b1fa4dd4538 100644
> --- a/net/ipv4/tcp.c
> +++ b/net/ipv4/tcp.c
> @@ -2571,6 +2571,17 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
> release_sock(sk);
> return err;
> }
> + case TCP_FASTOPEN_KEY: {
> + __u8 key[TCP_FASTOPEN_KEY_LENGTH];
> +
> + if (optlen != sizeof(key))
> + return -EINVAL;
> +
> + if (copy_from_user(key, optval, optlen))
> + return -EFAULT;
> +
> + return tcp_fastopen_reset_cipher(net, sk, key, sizeof(key));
> + }
> default:
> /* fallthru */
> break;
> @@ -3157,6 +3168,28 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
> return -EFAULT;
> return 0;
>
> + case TCP_FASTOPEN_KEY: {
> + __u8 key[TCP_FASTOPEN_KEY_LENGTH];
> + struct tcp_fastopen_context *ctx;
> +
> + if (get_user(len, optlen))
> + return -EFAULT;
> +
> + rcu_read_lock();
> + ctx = rcu_dereference(icsk->icsk_accept_queue.fastopenq.ctx);
> + if (ctx)
> + memcpy(key, ctx->key, sizeof(key));
> + else
> + len = 0;
> + rcu_read_unlock();
> +
> + len = min_t(unsigned int, len, sizeof(key));
> + if (put_user(len, optlen))
> + return -EFAULT;
> + if (copy_to_user(optval, key, len))
> + return -EFAULT;
> + return 0;
> + }
> case TCP_THIN_LINEAR_TIMEOUTS:
> val = tp->thin_lto;
> break;
> diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
> index 7ee4aadcdd71..21075ce19cb6 100644
> --- a/net/ipv4/tcp_fastopen.c
> +++ b/net/ipv4/tcp_fastopen.c
> @@ -29,7 +29,7 @@ void tcp_fastopen_init_key_once(struct net *net)
> * for a valid cookie, so this is an acceptable risk.
> */
> get_random_bytes(key, sizeof(key));
> - tcp_fastopen_reset_cipher(net, key, sizeof(key));
> + tcp_fastopen_reset_cipher(net, NULL, key, sizeof(key));
> }
>
> static void tcp_fastopen_ctx_free(struct rcu_head *head)
> @@ -40,6 +40,16 @@ static void tcp_fastopen_ctx_free(struct rcu_head *head)
> kfree(ctx);
> }
>
> +void tcp_fastopen_destroy_cipher(struct sock *sk)
> +{
> + struct tcp_fastopen_context *ctx;
> +
> + ctx = rcu_dereference_protected(
> + inet_csk(sk)->icsk_accept_queue.fastopenq.ctx, 1);
> + if (ctx)
> + call_rcu(&ctx->rcu, tcp_fastopen_ctx_free);
> +}
> +
> void tcp_fastopen_ctx_destroy(struct net *net)
> {
> struct tcp_fastopen_context *ctxt;
> @@ -55,10 +65,12 @@ void tcp_fastopen_ctx_destroy(struct net *net)
> call_rcu(&ctxt->rcu, tcp_fastopen_ctx_free);
> }
>
> -int tcp_fastopen_reset_cipher(struct net *net, void *key, unsigned int len)
> +int tcp_fastopen_reset_cipher(struct net *net, struct sock *sk,
> + void *key, unsigned int len)
> {
> - int err;
> struct tcp_fastopen_context *ctx, *octx;
> + struct fastopen_queue *q;
> + int err;
>
> ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
> if (!ctx)
> @@ -79,27 +91,39 @@ error: kfree(ctx);
> }
> memcpy(ctx->key, key, len);
>
> - spin_lock(&net->ipv4.tcp_fastopen_ctx_lock);
>
> - octx = rcu_dereference_protected(net->ipv4.tcp_fastopen_ctx,
> - lockdep_is_held(&net->ipv4.tcp_fastopen_ctx_lock));
> - rcu_assign_pointer(net->ipv4.tcp_fastopen_ctx, ctx);
> - spin_unlock(&net->ipv4.tcp_fastopen_ctx_lock);
> + if (sk) {
> + q = &inet_csk(sk)->icsk_accept_queue.fastopenq;
> + spin_lock_bh(&q->lock);
> + octx = rcu_dereference_protected(q->ctx,
> + lockdep_is_held(&q->lock));
> + rcu_assign_pointer(q->ctx, ctx);
> + spin_unlock_bh(&q->lock);
> + } else {
> + spin_lock(&net->ipv4.tcp_fastopen_ctx_lock);
> + octx = rcu_dereference_protected(net->ipv4.tcp_fastopen_ctx,
> + lockdep_is_held(&net->ipv4.tcp_fastopen_ctx_lock));
> + rcu_assign_pointer(net->ipv4.tcp_fastopen_ctx, ctx);
> + spin_unlock(&net->ipv4.tcp_fastopen_ctx_lock);
> + }
>
> if (octx)
> call_rcu(&octx->rcu, tcp_fastopen_ctx_free);
> return err;
> }
>
> -static bool __tcp_fastopen_cookie_gen(struct net *net,
> - const void *path,
> +static bool __tcp_fastopen_cookie_gen(struct sock *sk, const void *path,
> struct tcp_fastopen_cookie *foc)
> {
> struct tcp_fastopen_context *ctx;
> bool ok = false;
>
> rcu_read_lock();
> - ctx = rcu_dereference(net->ipv4.tcp_fastopen_ctx);
> +
> + ctx = rcu_dereference(inet_csk(sk)->icsk_accept_queue.fastopenq.ctx);
> + if (!ctx)
> + ctx = rcu_dereference(sock_net(sk)->ipv4.tcp_fastopen_ctx);
> +
> if (ctx) {
> crypto_cipher_encrypt_one(ctx->tfm, foc->val, path);
> foc->len = TCP_FASTOPEN_COOKIE_SIZE;
> @@ -115,7 +139,7 @@ static bool __tcp_fastopen_cookie_gen(struct net *net,
> *
> * XXX (TFO) - refactor when TCP_FASTOPEN_COOKIE_SIZE != AES_BLOCK_SIZE.
> */
> -static bool tcp_fastopen_cookie_gen(struct net *net,
> +static bool tcp_fastopen_cookie_gen(struct sock *sk,
> struct request_sock *req,
> struct sk_buff *syn,
> struct tcp_fastopen_cookie *foc)
> @@ -124,7 +148,7 @@ static bool tcp_fastopen_cookie_gen(struct net *net,
> const struct iphdr *iph = ip_hdr(syn);
>
> __be32 path[4] = { iph->saddr, iph->daddr, 0, 0 };
> - return __tcp_fastopen_cookie_gen(net, path, foc);
> + return __tcp_fastopen_cookie_gen(sk, path, foc);
> }
>
> #if IS_ENABLED(CONFIG_IPV6)
> @@ -132,13 +156,13 @@ static bool tcp_fastopen_cookie_gen(struct net *net,
> const struct ipv6hdr *ip6h = ipv6_hdr(syn);
> struct tcp_fastopen_cookie tmp;
>
> - if (__tcp_fastopen_cookie_gen(net, &ip6h->saddr, &tmp)) {
> + if (__tcp_fastopen_cookie_gen(sk, &ip6h->saddr, &tmp)) {
> struct in6_addr *buf = &tmp.addr;
> int i;
>
> for (i = 0; i < 4; i++)
> buf->s6_addr32[i] ^= ip6h->daddr.s6_addr32[i];
> - return __tcp_fastopen_cookie_gen(net, buf, foc);
> + return __tcp_fastopen_cookie_gen(sk, buf, foc);
> }
> }
> #endif
> @@ -313,7 +337,7 @@ struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
> goto fastopen;
>
> if (foc->len >= 0 && /* Client presents or requests a cookie */
> - tcp_fastopen_cookie_gen(sock_net(sk), req, skb, &valid_foc) &&
> + tcp_fastopen_cookie_gen(sk, req, skb, &valid_foc) &&
> foc->len == TCP_FASTOPEN_COOKIE_SIZE &&
> foc->len == valid_foc.len &&
> !memcmp(foc->val, valid_foc.val, foc->len)) {
> diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
> index 5418ecf03b78..d80e1313200a 100644
> --- a/net/ipv4/tcp_ipv4.c
> +++ b/net/ipv4/tcp_ipv4.c
> @@ -1892,6 +1892,7 @@ void tcp_v4_destroy_sock(struct sock *sk)
>
> /* If socket is aborted during connect operation */
> tcp_free_fastopen_req(tp);
> + tcp_fastopen_destroy_cipher(sk);
> tcp_saved_syn_free(tp);
>
> sk_sockets_allocated_dec(sk);
> --
> 2.15.0.rc1.287.g2b38de12cc-goog
>
^ permalink raw reply
* Re: Regression in throughput between kvm guests over virtual bridge
From: Matthew Rosato @ 2017-10-18 20:17 UTC (permalink / raw)
To: Wei Xu; +Cc: Jason Wang, netdev, davem, mst
In-Reply-To: <20171012183132.qrbgnmvki6lpgt4a@Wei-Dev>
On 10/12/2017 02:31 PM, Wei Xu wrote:
> On Thu, Oct 05, 2017 at 04:07:45PM -0400, Matthew Rosato wrote:
>>
>> Ping... Jason, any other ideas or suggestions?
>
> Hi Matthew,
> Recently I am doing similar test on x86 for this patch, here are some,
> differences between our testbeds.
>
> 1. It is nice you have got improvement with 50+ instances(or connections here?)
> which would be quite helpful to address the issue, also you've figured out the
> cost(wait/wakeup), kindly reminder did you pin uperf client/server along the whole
> path besides vhost and vcpu threads?
Was not previously doing any pinning whatsoever, just reproducing an
environment that one of our testers here was running. Reducing guest
vcpu count from 4->1, still see the regression. Then, pinned each vcpu
thread and vhost thread to a separate host CPU -- still made no
difference (regression still present).
>
> 2. It might be useful to short the traffic path as a reference, What I am running
> is briefly like:
> pktgen(host kernel) -> tap(x) -> guest(DPDK testpmd)
>
> The bridge driver(br_forward(), etc) might impact performance due to my personal
> experience, so eventually I settled down with this simplified testbed which fully
> isolates the traffic from both userspace and host kernel stack(1 and 50 instances,
> bridge driver, etc), therefore reduces potential interferences.
>
> The down side of this is that it needs DPDK support in guest, has this ever be
> run on s390x guest? An alternative approach is to directly run XDP drop on
> virtio-net nic in guest, while this requires compiling XDP inside guest which needs
> a newer distro(Fedora 25+ in my case or Ubuntu 16.10, not sure).
>
I made an attempt at DPDK, but it has not been run on s390x as far as
I'm aware and didn't seem trivial to get working.
So instead I took your alternate suggestion & did:
pktgen(host) -> tap(x) -> guest(xdp_drop)
When running this setup, I am not able to reproduce the regression. As
mentioned previously, I am also unable to reproduce when running one end
of the uperf connection from the host - I have only ever been able to
reproduce when both ends of the uperf connection are running within a guest.
> 3. BTW, did you enable hugepage for your guest? It would performance more
> or less depends on the memory demand when generating traffic, I didn't see
> similar command lines in yours.
>
s390x does not currently support passing through hugetlb backing via
QEMU mem-path.
^ permalink raw reply
* [PATCH net-next v2 0/2] ipv6: fixes for RTF_CACHE entries
From: Paolo Abeni @ 2017-10-18 20:23 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Wei Wang, Martin KaFai Lau, Eric Dumazet,
Hannes Frederic Sowa
This series addresses 3 different but related issues with RTF_CACHE introduced
by the recent refactory.
patch 1 restore the gc timer for such routes
patch 2 removes the aged out dst from the fib tree
v1 -> v2:
- dropped the for ip route show cache
- avoid touching dst.obsolete when the dst is aged out
Paolo Abeni (2):
ipv6: start fib6 gc on RTF_CACHE dst creation
ipv6: remove from fib tree aged out RTF_CACHE dst
net/ipv6/route.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
--
2.13.6
^ permalink raw reply
* [PATCH net-next v2 1/2] ipv6: start fib6 gc on RTF_CACHE dst creation
From: Paolo Abeni @ 2017-10-18 20:23 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Wei Wang, Martin KaFai Lau, Eric Dumazet,
Hannes Frederic Sowa
In-Reply-To: <cover.1508358132.git.pabeni@redhat.com>
After the commit Fixes: 2b760fcf5cfb ("ipv6: hook up exception
table to store dst cache"), the fib6 gc is not started after
the creation of a RTF_CACHE via a redirect or pmtu update, since
fib6_add() isn't invoked anymore for such dsts.
We need the fib6 gc to run periodically to clean the RTF_CACHE,
or the dst will stay there forever.
Fix it by explicitly calling fib6_force_start_gc() on successful
exception creation. gc_args->more accounting will ensure that
the gc timer will run for whatever time needed to properly
clean the table.
Fixes: 2b760fcf5cfb ("ipv6: hook up exception table to store dst cache")
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Acked-by: Wei Wang <weiwan@google.com>
Acked-by: Martin KaFai Lau <kafai@fb.com>
---
net/ipv6/route.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 01a103c23a6c..5c27313803d2 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1340,8 +1340,10 @@ static int rt6_insert_exception(struct rt6_info *nrt,
spin_unlock_bh(&rt6_exception_lock);
/* Update fn->fn_sernum to invalidate all cached dst */
- if (!err)
+ if (!err) {
fib6_update_sernum(ort);
+ fib6_force_start_gc(net);
+ }
return err;
}
--
2.13.6
^ permalink raw reply related
* [PATCH net-next v2 2/2] ipv6: remove from fib tree aged out RTF_CACHE dst
From: Paolo Abeni @ 2017-10-18 20:23 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Wei Wang, Martin KaFai Lau, Eric Dumazet,
Hannes Frederic Sowa
In-Reply-To: <cover.1508358132.git.pabeni@redhat.com>
The commit 2b760fcf5cfb ("ipv6: hook up exception table to store
dst cache") partially reverted 1e2ea8ad37be ("ipv6: set
dst.obsolete when a cached route has expired").
As a result, RTF_CACHE dst referenced outside the fib tree will
not be removed until the next sernum change; dst_check() does not
fail on aged-out dst, and dst->__refcnt can't decrease: the aged
out dst will stay valid for a potentially unlimited time after the
timeout expiration.
This change explicitly removes RTF_CACHE dst from the fib tree when
aged out. The rt6_remove_exception() logic will then obsolete the
dst and other entities will drop the related reference on next
dst_check().
v1 -> v2:
- do not touch dst.obsolete in rt6_remove_exception(), not needed
Fixes: 2b760fcf5cfb ("ipv6: hook up exception table to store dst cache")
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
net/ipv6/route.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 5c27313803d2..a4a7f199120e 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1575,8 +1575,11 @@ static void rt6_age_examine_exception(struct rt6_exception_bucket *bucket,
{
struct rt6_info *rt = rt6_ex->rt6i;
- if (atomic_read(&rt->dst.__refcnt) == 1 &&
- time_after_eq(now, rt->dst.lastuse + gc_args->timeout)) {
+ /* we are pruning and obsoleting the exception route even if others
+ * have still reference to it, so that on next dst_check() such
+ * reference can be dropped
+ */
+ if (time_after_eq(now, rt->dst.lastuse + gc_args->timeout)) {
RT6_TRACE("aging clone %p\n", rt);
rt6_remove_exception(bucket, rt6_ex);
return;
--
2.13.6
^ permalink raw reply related
* Re: [PATCH net-next 3/3] ipv6: obsolete cached dst when removing them from fib tree
From: Paolo Abeni @ 2017-10-18 20:30 UTC (permalink / raw)
To: Martin KaFai Lau, Wei Wang
Cc: Eric Dumazet, Xin Long, Linux Kernel Network Developers,
David S. Miller, Hannes Frederic Sowa
In-Reply-To: <20171018190513.dtoqpzjfyapo2iie@kafai-mbp.dhcp.thefacebook.com>
On Wed, 2017-10-18 at 12:05 -0700, Martin KaFai Lau wrote:
> Another thing (not limited to this case),
>
> Considering we have a limited size in the exception table now and
> the oldest one will get removed when the table is full,
> do we still need to purge this periodically in gc?
At least in some scenarios we have only a few entries in the exception
table.
> I would like to see the IPv6's gc eventually goes away.
>
> If we need to expire the pmtu value of a RTF_CACHE rt,
> can dst.expires be checked during the lookup (like what
> ipv4 is doing) and then remove it from the exception table?
Currently the gc also performs validation vs the related neigh for
GATEWAY dst. That looks potentially quite expensive, as we currently
have a per neighbour atomic refcount (e.g. if the same dst is cached on
different CPUs)
Cheers,
Paolo
^ permalink raw reply
* [PATCH] i40e/virtchnl: fix application of sizeof to pointer
From: Gustavo A. R. Silva @ 2017-10-18 20:34 UTC (permalink / raw)
To: Jeff Kirsher; +Cc: intel-wired-lan, netdev, linux-kernel, Gustavo A. R. Silva
sizeof when applied to a pointer typed expression gives the size of
the pointer.
The proper fix in this particular case is to code sizeof(*vfres)
instead of sizeof(vfres).
This issue was detected with the help of Coccinelle.
Signed-off-by: Gustavo A. R. Silva <garsilva@embeddedor.com>
---
This code was tested by compilation only.
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index f8a794b..56dd1e8 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -2086,7 +2086,7 @@ static int i40e_vc_request_queues_msg(struct i40e_vf *vf, u8 *msg, int msglen)
}
return i40e_vc_send_msg_to_vf(vf, VIRTCHNL_OP_REQUEST_QUEUES, 0,
- (u8 *)vfres, sizeof(vfres));
+ (u8 *)vfres, sizeof(*vfres));
}
/**
--
2.7.4
^ permalink raw reply related
* Re: [PATCH net-next] tcp: socket option to set TCP fast open key
From: Eric Dumazet @ 2017-10-18 20:37 UTC (permalink / raw)
To: Christoph Paasch
Cc: Yuchung Cheng, David Miller, netdev, Neal Cardwell,
maheshb@google.com
In-Reply-To: <20171018201344.GQ73751@Chimay.local>
On Wed, Oct 18, 2017 at 1:13 PM, Christoph Paasch <cpaasch@apple.com> wrote:
>
> Hello Yuchung,
>
> On 18/10/17 - 11:22:51, Yuchung Cheng wrote:
> > New socket option TCP_FASTOPEN_KEY to allow different keys per
> > listener. The listener by default uses the global key until the
> > socket option is set. The key is a 16 bytes long binary data. This
> > option has no effect on regular non-listener TCP sockets.
>
> can you explain what the use-case is to have per-listener TFO keys?
>
Security aspects. You want to be able to change keys whenever you
want, on an application basis.
^ permalink raw reply
* Re: [PATCH] mac80211: aggregation: Convert timers to use timer_setup()
From: Johannes Berg @ 2017-10-18 20:50 UTC (permalink / raw)
To: Kees Cook; +Cc: linux-wireless, David S. Miller, Network Development, LKML
In-Reply-To: <CAGXu5jKY5rTuR_w=zj5Bz06f9OrW35eD4sYfkai2Gac_edG4ag@mail.gmail.com>
On Wed, 2017-10-18 at 07:19 -0700, Kees Cook wrote:
> On Wed, Oct 18, 2017 at 3:29 AM, Johannes Berg
> <johannes@sipsolutions.net> wrote:
> > > This has been the least trivial timer conversion yet. Given the use of
> > > RCU and other things I may not even know about, I'd love to get a close
> > > look at this. I *think* this is correct, as it will re-lookup the tid
> > > entries when firing the timer.
> >
> > I'm not really sure why you're doing the lookup again? That seems
> > pointless, since you already have the right structure, and already rely
> > on it being valid. You can't really get a new struct assigned to the
> > same TID without the old one being destroyed.
>
> I couldn't tell what the lifetime expectation was, so I left the
> re-lookup. I assumed it was possible to have a timer fire after the
> structure had been removed from the station structure.
Oh, right, I guess that would've been possible in theory. It's not
actually possible though since the aggregation sessions can't live on
without a station, so I've already made a follow-up patch to remove the
indirection.
johannes
^ permalink raw reply
* Re: RFC(v2): Audit Kernel Container IDs
From: Paul Moore @ 2017-10-18 20:56 UTC (permalink / raw)
To: James Bottomley
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA, mszeredi-H+wXaHxf7aLQT0dZR+AlfA,
Andy Lutomirski, jlayton-H+wXaHxf7aLQT0dZR+AlfA,
Carlos O'Donell, API, Linux Containers, Linux Kernel, Viro,
David Howells, Linux FS Devel, linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
Eric W. Biederman, Simo Sorce, Development, Casey Schaufler,
Eric Paris, Steve Grubb, trondmy-7I+n7zu2hftEKMMhf/gKZA
In-Reply-To: <1508255091.3129.27.camel-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk@public.gmane.org>
On Tue, Oct 17, 2017 at 11:44 AM, James Bottomley
<James.Bottomley-JuX6DAaQMKPCXq6kfMZ53/egYHeGw8Jk@public.gmane.org> wrote:
> On Tue, 2017-10-17 at 11:28 -0400, Simo Sorce wrote:
>> > Without a *kernel* policy on containerIDs you can't say what
>> > security policy is being exempted.
>>
>> The policy has been basically stated earlier.
>>
>> A way to track a set of processes from a specific point in time
>> forward. The name used is "container id", but it could be anything.
>> This marker is mostly used by user space to track process hierarchies
>> without races, these processes can be very privileged, and must not
>> be allowed to change the marker themselves when granted the current
>> common capabilities.
>>
>> Is this a good enough description ? If not can you clarify your
>> expectations ?
>
> I think you mean you want to be able to apply a label to a process
> which is inherited across forks. The label should only be susceptible
> to modification by something possessing a capability (which one TBD).
> The idea is that processes spawned into a container would be labelled
> by the container orchestration system. It's unclear what should happen
> to processes using nsenter after the fact, but policy for that should
> be up to the orchestration system.
>
> The label will be used as a tag for audit information.
>
> I think you were missing label inheritance above.
That is a pretty good summary of what we want to do, and what Richard
and I have discussed while brainstorming this offline. The details
may not have translated well into those initial emails from Richard,
but I think you've got the idea, even if some of the smaller details
are still TBD. FWIW, right now I'm not as worried about the exact
capability or the size of the audit container ID, I think those things
will sort themselves out as we progress through the implementation,
especially once we get to the next stage when we start to allow copies
of the audit records to be routed to audit daemons running inside
containers (note well that I said "copies", the host system still sees
all).
> The security implications are that anything that can change the label
> could also hide itself and its doings from the audit system and thus
> would be used as a means to evade detection. I actually think this
> means the label should be write once (once you've set it, you can't
> change it) ...
Richard and I have talked about a write once approach, but the
thinking was that you may want to allow a nested container
orchestrator (Why? I don't know, but people always want to do the
craziest things.) and a write-once policy makes that impossible. If
we punt on the nested orchestrator, I believe we can seriously think
about a write-once policy to simplify things.
A bit off topic, but I've also wondered about not even implementing
read access, just to help ensure the audit container ID wouldn't be
abused, but I'm not sure how practical that will be. Something else
to sort out during the RFC phase of the implementation with the
container orchestrators.
> ... and orchestration systems should begin as unlabelled
> processes allowing them to do arbitrary forks.
My current thinking is that the default state is to start unlabeled (I
just vomited a little into my SELinux hat); in other words
init/systemd/PID-1 in the host system starts with an "unset" audit
container ID. This not only helps define the host system (anything
that has an unset audit container ID) but provides a blank slate for
the orchestrator(s).
> For nested containers, I actually think the label should be
> hierarchical, so you can add a label for the new nested container but
> it still also contains its parents label as well.
I haven't made up my mind on this completely just yet, but I'm
currently of the mindset that supporting multiple audit container IDs
on a given process is not a good idea.
--
paul moore
www.paul-moore.com
^ permalink raw reply
* Re: Problems with mvneta
From: Thomas Petazzoni @ 2017-10-18 20:55 UTC (permalink / raw)
To: Sven Müller
Cc: Grégory Clement, Antoine Ténart, netdev, Marcin Wojtas
In-Reply-To: <20171018223425.42ce7a74@gmx.de>
Hello,
I'm adding my colleagues Grégory Clement and Antoine Ténart in Cc, as
well as Marcin Wojtas, who also worked on mvneta, and the netdev
mailing list. I'm keeping your full message below so that others can
read the context.
On Wed, 18 Oct 2017 22:34:25 +0200, Sven Müller wrote:
> I've found your email address in the kernel sources of the mvneta driver. I didn't find a bug system on free-electrons.com. And on kernel.org searching for mvneta wasn't really helpful.
There is a bug tracker for the Linux kernel at
https://bugzilla.kernel.org/. However, I indeed wouldn't be notified of
bug reports against mvneta.
> Some people including me hacked the Zyxel NSA-326 some time ago. The whole thread you can find here:
>
> https://forum.doozan.com/read.php?2,27108
>
> Until kernel 4.10.10 everything worked great. I didn't test 4.11. But any higher kernel version (tested 4.12., 4.13) causes network problems with nfs. I described it here:
>
> https://forum.doozan.com/read.php?2,27108,37699#msg-37699
>
> Transfering files not with full speed but over a longer period of time, e.g. playing music files over nfs or reading a lot of smaller files causes the error:
>
> Sep 27 17:35:37 nas kernel: rpc-srv/tcp: nfsd: sent only 36488 when sending 65644 bytes - shutting down socket
>
> After that message the network is down. I have to reboot the device in order to get any network connectivity again. And how I wrote: 4.10.10 works perfectly. 4.12 produced a lot of this errors, 4.13 seems to be a little bit better.
>
> Unfortunately I didn't find a way to reproduce this problem directly. It occurs after 5 minutes up to one hour of transferring files via nfs.
>
> If you are interested in fixing this bug, I would like to support you with providing you any information I can find on my system and testing.
>
> My kernel config, which is working in 4.10.10 and producing the nfs problem in 4.12 and 4.13:
>
> https://paste.pound-python.org/show/RCaG9J4yBy79K3NL5F1
>
> and the device tree:
>
> https://paste.pound-python.org/show/UiLpMgUERuCddHOn6Vsp/
There have been a few changes in the mvneta code between 4.10 and 4.12,
but not many of them look potentially problematic.
f95936cca6a8410ebdaf164bc5d3ade9e1de5bdb net: mvneta: Adjust six checks for null pointers
d441b688a1bce8e2e1b43d8090738c306dd09131 net: mvneta: Use kmalloc_array() in mvneta_txq_init()
5d6312ed57a909c86bb9472b2bbc012539392e7d net: mvneta: Improve two size determinations in mvneta_init()
2911063011fc7adcb43c93e9c3e9dc7798f459f5 net: mvneta: Use devm_kmalloc_array() in mvneta_init()
82960fff09bc394e2a33d5369969410699c04861 net: mvneta: fix failed to suspend if WOL is enabled
d6956ac87b5ff6841b09c273a70de86200d82019 net: mvneta: set rx mode during resume if interface is running
a38d20d791fdcd79ebccda15a8308a6d8ada6e1c net: mvneta: add RGMII_RXID and RGMII_TXID support
9768b45ceb0bc7bdee61837afad331dd6bf7977f net: mvneta: support suspend and resume
4581be42fce5e1d208cbeb8e78df3f1b4673eff7 net: mvneta: make mvneta_eth_tool_ops static
9303ab2b3402b60f6c39abfdbfa4ce00fce8bee4 net: mvneta: fix build errors when linux/phy*.h is removed from net/dsa.h
b60a00f9c5f14695991cb77dce7e926623269d88 net: mvneta: implement .set_wol and .get_wol
6ad20165d376fa07919a70e4f43dfae564601829 drivers: net: generalize napi_complete_done()
a29b6235560a1ed10c8e1a73bfc616a66b802b90 net: mvneta: add BQL support
2a90f7e1d5d04e4f1060268e0b55a2c702bbd67a net: mvneta: add xmit_more support
bc1f44709cf27fb2a5766cadafe7e2ad5e9cb221 net: make ndo_get_stats64 a void function
The only ones that really could have an impact are:
6ad20165d376fa07919a70e4f43dfae564601829 drivers: net: generalize napi_complete_done()
a29b6235560a1ed10c8e1a73bfc616a66b802b90 net: mvneta: add BQL support
2a90f7e1d5d04e4f1060268e0b55a2c702bbd67a net: mvneta: add xmit_more support
Could you try to take mvneta* from Linux 4.10, put that in Linux 4.12,
and see if you can still produce the problem? I'd like to first make
sure the problem really is inside mvneta, and not in some other place.
Thanks!
Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* Re: [PATCH] mac80211: aggregation: Convert timers to use timer_setup()
From: Kees Cook @ 2017-10-18 21:02 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, David S. Miller, Network Development, LKML
In-Reply-To: <1508359811.2674.56.camel@sipsolutions.net>
On Wed, Oct 18, 2017 at 1:50 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Wed, 2017-10-18 at 07:19 -0700, Kees Cook wrote:
>> On Wed, Oct 18, 2017 at 3:29 AM, Johannes Berg
>> <johannes@sipsolutions.net> wrote:
>> > > This has been the least trivial timer conversion yet. Given the use of
>> > > RCU and other things I may not even know about, I'd love to get a close
>> > > look at this. I *think* this is correct, as it will re-lookup the tid
>> > > entries when firing the timer.
>> >
>> > I'm not really sure why you're doing the lookup again? That seems
>> > pointless, since you already have the right structure, and already rely
>> > on it being valid. You can't really get a new struct assigned to the
>> > same TID without the old one being destroyed.
>>
>> I couldn't tell what the lifetime expectation was, so I left the
>> re-lookup. I assumed it was possible to have a timer fire after the
>> structure had been removed from the station structure.
>
> Oh, right, I guess that would've been possible in theory. It's not
> actually possible though since the aggregation sessions can't live on
> without a station, so I've already made a follow-up patch to remove the
> indirection.
Okay, cool, thanks.
It seems like I have a similar case in the iwlwifi driver too, but
it's different enough that I'm not sure about that one either. I'll
send that when I've got it ready.
-Kees
--
Kees Cook
Pixel Security
^ permalink raw reply
* Re: [PATCH net-next v7 1/5] bpf: Add file mode configuration into bpf maps
From: Daniel Borkmann @ 2017-10-18 21:14 UTC (permalink / raw)
To: Chenbo Feng, netdev, SELinux, linux-security-module
Cc: Jeffrey Vander Stoep, Alexei Starovoitov, lorenzo,
Stephen Smalley, James Morris, Paul Moore, Chenbo Feng
In-Reply-To: <20171018200026.146093-2-chenbofeng.kernel@gmail.com>
On 10/18/2017 10:00 PM, Chenbo Feng wrote:
> From: Chenbo Feng <fengc@google.com>
>
> Introduce the map read/write flags to the eBPF syscalls that returns the
> map fd. The flags is used to set up the file mode when construct a new
> file descriptor for bpf maps. To not break the backward capability, the
> f_flags is set to O_RDWR if the flag passed by syscall is 0. Otherwise
> it should be O_RDONLY or O_WRONLY. When the userspace want to modify or
> read the map content, it will check the file mode to see if it is
> allowed to make the change.
>
> Signed-off-by: Chenbo Feng <fengc@google.com>
> Acked-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
^ permalink raw reply
* Re: [PATCH net-next v12] openvswitch: enable NSH support
From: Jiri Benc @ 2017-10-18 21:19 UTC (permalink / raw)
To: Yi Yang; +Cc: netdev, dev, e, pshelar, davem
In-Reply-To: <1508162009-30359-1-git-send-email-yi.y.yang@intel.com>
On Mon, 16 Oct 2017 21:53:29 +0800, Yi Yang wrote:
> +static int set_nsh(struct sk_buff *skb, struct sw_flow_key *flow_key,
> + const struct nlattr *a)
> +{
> + struct nshhdr *nh;
> + size_t length;
> + int err;
> + u8 flags;
> + u8 ttl;
> + int i;
> +
> + struct ovs_key_nsh key;
> + struct ovs_key_nsh mask;
> +
> + err = nsh_key_from_nlattr(a, &key, &mask);
> + if (err)
> + return err;
> +
> + /* Make sure the NSH base header is there */
> + err = skb_ensure_writable(skb, skb_network_offset(skb) +
> + NSH_BASE_HDR_LEN);
> + if (unlikely(err))
> + return err;
> +
> + nh = nsh_hdr(skb);
> + length = nsh_hdr_len(nh);
> +
> + /* Make sure the whole NSH header is there */
> + err = skb_ensure_writable(skb, skb_network_offset(skb) +
> + length);
Calling skb_ensure_writable twice is an unnecessary waste in the fast
path. If anything, the first call should be changed to pskb_may_pull.
But what we really should do here is to move the header only once. We
know how much data we're going to write, we have everything stored in
the key and can calculate it from there.
length = NSH_BASE_HDR_LEN;
switch (flow_key->nsh.base.mdtype) {
case NSH_MD_TYPE1:
length += sizeof(struct ovs_nsh_key_md1);
break;
case NSH_MD_TYPE2:
length += whatever_way_we_store_the_tlvs_in_flow_key;
break;
}
err = skb_ensure_writable(skb, skb_network_offset(skb) + length);
However, set_nsh does not support MD type 2, thus the second case is a
dead code. In both switches in this function. As such, it should be
removed and added only when MD type 2 is introduced. I'd still keep the
overall logic to ease the future addition, though. This boils down to:
length = NSH_BASE_HDR_LEN;
/* Assume MD type 1. This function cannot be called for anything
* else currently. When MD type 2 is added, the line below will
* have to be turned into a switch on flow_key->nsh.base.mdtype.
*/
length += sizeof(struct ovs_nsh_key_md1);
err = skb_ensure_writable(skb, skb_network_offset(skb) + length);
...
flow_key->nsh.base.path_hdr = nh->path_hdr;
/* Only MD type 1, see the comment above. */
for (i = 0; i < NSH_MD1_CONTEXT_SIZE; i++) {
...
Please verify I'm not missing something.
It seems we also rely on the user space checking first whether the
packet is indeed compatible with the pushed key/mask. Most importantly,
that it's of the same mdtype and (in the future) that the MD type 2
TLVs being written actually fit. Seems this is done the same way in the
other set_* actions, thus fine with me.
Jiri
^ permalink raw reply
* [PATCH net-next] tcp: fix tcp_send_syn_data()
From: Eric Dumazet @ 2017-10-18 21:20 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Yuchung Cheng, Eric Dumazet
From: Eric Dumazet <edumazet@google.com>
syn_data was allocated by sk_stream_alloc_skb(), meaning
its destructor and _skb_refdst fields are mangled.
We need to call tcp_skb_tsorted_anchor_cleanup() before
calling kfree_skb() or kernel crashes.
Bug was reported by syzkaller bot.
Fixes: e2080072ed2d ("tcp: new list for sent but unacked skbs for RACK recovery")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Dmitry Vyukov <dvyukov@google.com>
---
net/ipv4/tcp_output.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 53dc1267c85e668d9a6d5d60d24e6101f7a9c56b..988733f289c8c43f3ed88a9ae1b7f272ab8de1a2 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -3383,6 +3383,7 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
int copied = copy_from_iter(skb_put(syn_data, space), space,
&fo->data->msg_iter);
if (unlikely(!copied)) {
+ tcp_skb_tsorted_anchor_cleanup(syn_data);
kfree_skb(syn_data);
goto fallback;
}
^ permalink raw reply related
* Re: [PATCH net-next] tcp: fix tcp_send_syn_data()
From: Yuchung Cheng @ 2017-10-18 21:40 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev, Eric Dumazet
In-Reply-To: <1508361630.31614.142.camel@edumazet-glaptop3.roam.corp.google.com>
On Wed, Oct 18, 2017 at 2:20 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> From: Eric Dumazet <edumazet@google.com>
>
> syn_data was allocated by sk_stream_alloc_skb(), meaning
> its destructor and _skb_refdst fields are mangled.
>
> We need to call tcp_skb_tsorted_anchor_cleanup() before
> calling kfree_skb() or kernel crashes.
>
> Bug was reported by syzkaller bot.
>
> Fixes: e2080072ed2d ("tcp: new list for sent but unacked skbs for RACK recovery")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Reported-by: Dmitry Vyukov <dvyukov@google.com>
Acked-by: Yuchung Cheng <ycheng@google.com>
Thanks for the fix!
> ---
> net/ipv4/tcp_output.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
> index 53dc1267c85e668d9a6d5d60d24e6101f7a9c56b..988733f289c8c43f3ed88a9ae1b7f272ab8de1a2 100644
> --- a/net/ipv4/tcp_output.c
> +++ b/net/ipv4/tcp_output.c
> @@ -3383,6 +3383,7 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
> int copied = copy_from_iter(skb_put(syn_data, space), space,
> &fo->data->msg_iter);
> if (unlikely(!copied)) {
> + tcp_skb_tsorted_anchor_cleanup(syn_data);
> kfree_skb(syn_data);
> goto fallback;
> }
>
>
^ permalink raw reply
* Re: [PATCH net 0/3] Fix for BPF devmap percpu allocation splat
From: Dennis Zhou @ 2017-10-18 21:45 UTC (permalink / raw)
To: Tejun Heo
Cc: Daniel Borkmann, davem, ast, john.fastabend, mark.rutland,
richard, sp3485, netdev, linux-kernel
In-Reply-To: <20171018132526.GC1302522@devbig577.frc2.facebook.com>
Hi Daniel and Tejun,
On Wed, Oct 18, 2017 at 06:25:26AM -0700, Tejun Heo wrote:
> > Daniel Borkmann (3):
> > mm, percpu: add support for __GFP_NOWARN flag
>
> This looks fine.
>
Looks good to me too.
> > bpf: fix splat for illegal devmap percpu allocation
> > bpf: do not test for PCPU_MIN_UNIT_SIZE before percpu allocations
>
> These look okay too but if it helps percpu allocator can expose the
> maximum size / alignment supported to take out the guessing game too.
>
I can add this once we've addressed the below if we want to.
> Also, the reason why PCPU_MIN_UNIT_SIZE is what it is is because
> nobody needed anything bigger. Increasing the size doesn't really
> cost much at least on 64bit archs. Is that something we want to be
> considering?
>
I'm not sure I see the reason we can't match the minimum allocation size
with the unit size? It seems weird to arbitrate the maximum allocation
size given a lower bound on the unit size.
Thanks,
Dennis
^ permalink raw reply
* Re: Kernel 4.13.0-rc4-next-20170811 - IP Routing / Forwarding performance vs Core/RSS number / HT on
From: Paweł Staszewski @ 2017-10-18 21:49 UTC (permalink / raw)
To: Florian Fainelli, Eric Dumazet
Cc: Paolo Abeni, Jesper Dangaard Brouer,
Linux Kernel Network Developers, Alexander Duyck
In-Reply-To: <6607c631-580d-825b-6205-6f6ee688ce32@gmail.com>
W dniu 2017-09-21 o 23:41, Florian Fainelli pisze:
> On 09/21/2017 02:26 PM, Paweł Staszewski wrote:
>>
>> W dniu 2017-08-15 o 11:11, Paweł Staszewski pisze:
>>> diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
>>> index
>>> 5e831de3103e2f7092c7fa15534def403bc62fb4..9472de846d5c0960996261cb2843032847fa4bf7
>>> 100644
>>> --- a/net/8021q/vlan_netlink.c
>>> +++ b/net/8021q/vlan_netlink.c
>>> @@ -143,6 +143,7 @@ static int vlan_newlink(struct net *src_net,
>>> struct net_device *dev,
>>> vlan->vlan_proto = proto;
>>> vlan->vlan_id = nla_get_u16(data[IFLA_VLAN_ID]);
>>> vlan->real_dev = real_dev;
>>> + dev->priv_flags |= (real_dev->priv_flags & IFF_XMIT_DST_RELEASE);
>>> vlan->flags = VLAN_FLAG_REORDER_HDR;
>>> err = vlan_check_real_dev(real_dev, vlan->vlan_proto,
>>> vlan->vlan_id);
>> Any plans for this patch to go normal into the kernel ?
> Would not this apply to pretty much any stacked device setup though? It
> seems like any network device that just queues up its packet on another
> physical device for actual transmission may need that (e.g: DSA, bond,
> team, more.?)
How far it is from applying this to the kernel ?
So far im using this on all my servers from about 3 months now without
problems
^ permalink raw reply
* Re: Kernel 4.13.0-rc4-next-20170811 - IP Routing / Forwarding performance vs Core/RSS number / HT on
From: Eric Dumazet @ 2017-10-18 21:54 UTC (permalink / raw)
To: Paweł Staszewski
Cc: Florian Fainelli, Paolo Abeni, Jesper Dangaard Brouer,
Linux Kernel Network Developers, Alexander Duyck
In-Reply-To: <efcafc22-bea6-8f01-2804-c16f69bbd448@itcare.pl>
On Wed, 2017-10-18 at 23:49 +0200, Paweł Staszewski wrote:
> How far it is from applying this to the kernel ?
>
> So far im using this on all my servers from about 3 months now without
> problems
It is a hack, and does not support properly bonding/team.
( If the real_dev->privflags IFF_XMIT_DST_RELEASE bit changes,
we want to update all the vlans at the same time )
We need something more sophisticated, and I had no time to spend on
this topic recently.
^ permalink raw reply
* Re: [PATCH 0/1] net: ethtool: add SmartNIC reset support
From: Scott Branden @ 2017-10-18 21:59 UTC (permalink / raw)
To: Andy Gospodarek
Cc: Andrew Lunn, David S. Miller, Allan W. Nielsen, Raju Lakkaraju,
Florian Fainelli, BCM Kernel Feedback, linux-kernel, Steve Lin,
netdev
In-Reply-To: <20171018213058.GD2847@C02RW35GFVH8.dhcp.broadcom.net>
+netdev@vger.kernel.org
On 17-10-18 02:30 PM, Andy Gospodarek wrote:
> On Wed, Oct 18, 2017 at 12:31:28PM -0700, Scott Branden wrote:
>> Hi Andrew,
>>
>>
>> On 17-10-18 12:16 PM, Andrew Lunn wrote:
>>>> Yes, there is also a management processor.
>>> O.K.
>>>
>>> Maybe it would be nice to add some more text to the commit message to
>>> make this clear. Define what an application processor is, and how it
>>> differs from a management processor. But othersize:
>> OK -will add more description to differentiate management processor vs.
>> application processor(s).
>>> Reviewed-by: Andrew Lunn <andrew@lunn.ch>
>>>
>>> I assume you have another kernel patch to actually make use of this?
>>> It is normal to post the user of a new API in the same series as the
>>> API.
>> I actually wanted to get agreement that the bit define could be added to
>> ethtool before implementing it in driver.
>> If this direction approved we'll implement in driver and submit with this
>> patch series.
> I just noticed that you did not also post this to netdev@vger.kernel.org. I
> suspect you are more likely to get review and acceptance if that list is cc'd.
>
> I'm not positive that Linus will take networking patches off this list.
>
>>> Andrew
>> Thanks,
>> Scott
^ permalink raw reply
* Re: [PATCH 1/1] net: ethtool: add support for reset of AP inside NIC interface.
From: Scott Branden @ 2017-10-18 21:59 UTC (permalink / raw)
To: David S. Miller, Allan W. Nielsen, Andrew Lunn, Raju Lakkaraju,
Florian Fainelli
Cc: BCM Kernel Feedback, linux-kernel, Steve Lin, netdev
In-Reply-To: <1508342496-5047-2-git-send-email-scott.branden@broadcom.com>
+netdev@vger.kernel.org
On 17-10-18 09:01 AM, Scott Branden wrote:
> Add ETH_RESET_AP to reset the application processor inside the NIC
> interface.
>
> Signed-off-by: Scott Branden <scott.branden@broadcom.com>
> ---
> include/uapi/linux/ethtool.h | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
> index 5bd1b1d..f927ab7 100644
> --- a/include/uapi/linux/ethtool.h
> +++ b/include/uapi/linux/ethtool.h
> @@ -1685,6 +1685,7 @@ enum ethtool_reset_flags {
> ETH_RESET_PHY = 1 << 6, /* Transceiver/PHY */
> ETH_RESET_RAM = 1 << 7, /* RAM shared between
> * multiple components */
> + ETH_RESET_AP = 1 << 8, /* Application processor */
>
> ETH_RESET_DEDICATED = 0x0000ffff, /* All components dedicated to
> * this interface */
^ permalink raw reply
* [PATCH net-next] spectrum: Convert fib event handlers to use container_of on info arg
From: David Ahern @ 2017-10-18 22:01 UTC (permalink / raw)
To: netdev; +Cc: jiri, idosch, David Ahern
Use container_of to convert the generic fib_notifier_info into
the event specific data structure.
Signed-off-by: David Ahern <dsahern@gmail.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---
.../net/ethernet/mellanox/mlxsw/spectrum_router.c | 29 +++++++++++++++++-----
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 2420f69797a9..12d471d2a90b 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -5209,25 +5209,35 @@ static void mlxsw_sp_router_fibmr_event_work(struct work_struct *work)
static void mlxsw_sp_router_fib4_event(struct mlxsw_sp_fib_event_work *fib_work,
struct fib_notifier_info *info)
{
+ struct fib_entry_notifier_info *fen_info;
+ struct fib_rule_notifier_info *fr_info;
+ struct fib_nh_notifier_info *fnh_info;
+
switch (fib_work->event) {
case FIB_EVENT_ENTRY_REPLACE: /* fall through */
case FIB_EVENT_ENTRY_APPEND: /* fall through */
case FIB_EVENT_ENTRY_ADD: /* fall through */
case FIB_EVENT_ENTRY_DEL:
- memcpy(&fib_work->fen_info, info, sizeof(fib_work->fen_info));
- /* Take referece on fib_info to prevent it from being
+ fen_info = container_of(info, struct fib_entry_notifier_info,
+ info);
+ fib_work->fen_info = *fen_info;
+ /* Take reference on fib_info to prevent it from being
* freed while work is queued. Release it afterwards.
*/
fib_info_hold(fib_work->fen_info.fi);
break;
case FIB_EVENT_RULE_ADD: /* fall through */
case FIB_EVENT_RULE_DEL:
- memcpy(&fib_work->fr_info, info, sizeof(fib_work->fr_info));
+ fr_info = container_of(info, struct fib_rule_notifier_info,
+ info);
+ fib_work->fr_info = *fr_info;
fib_rule_get(fib_work->fr_info.rule);
break;
case FIB_EVENT_NH_ADD: /* fall through */
case FIB_EVENT_NH_DEL:
- memcpy(&fib_work->fnh_info, info, sizeof(fib_work->fnh_info));
+ fnh_info = container_of(info, struct fib_nh_notifier_info,
+ info);
+ fib_work->fnh_info = *fnh_info;
fib_info_hold(fib_work->fnh_info.fib_nh->nh_parent);
break;
}
@@ -5236,16 +5246,23 @@ static void mlxsw_sp_router_fib4_event(struct mlxsw_sp_fib_event_work *fib_work,
static void mlxsw_sp_router_fib6_event(struct mlxsw_sp_fib_event_work *fib_work,
struct fib_notifier_info *info)
{
+ struct fib6_entry_notifier_info *fen6_info;
+ struct fib_rule_notifier_info *fr_info;
+
switch (fib_work->event) {
case FIB_EVENT_ENTRY_REPLACE: /* fall through */
case FIB_EVENT_ENTRY_ADD: /* fall through */
case FIB_EVENT_ENTRY_DEL:
- memcpy(&fib_work->fen6_info, info, sizeof(fib_work->fen6_info));
+ fen6_info = container_of(info, struct fib6_entry_notifier_info,
+ info);
+ fib_work->fen6_info = *fen6_info;
rt6_hold(fib_work->fen6_info.rt);
break;
case FIB_EVENT_RULE_ADD: /* fall through */
case FIB_EVENT_RULE_DEL:
- memcpy(&fib_work->fr_info, info, sizeof(fib_work->fr_info));
+ fr_info = container_of(info, struct fib_rule_notifier_info,
+ info);
+ fib_work->fr_info = *fr_info;
fib_rule_get(fib_work->fr_info.rule);
break;
}
--
2.1.4
^ permalink raw reply related
* pull-request: ieee802154 2017-10-18
From: Stefan Schmidt @ 2017-10-18 22:03 UTC (permalink / raw)
To: davem; +Cc: linux-wpan, alex.aring, marcel, netdev, Stefan Schmidt
From: Stefan Schmidt <stefan@osg.samsung.com>
Hello Dave.
Please find below a pull request from the ieee802154 subsystem for net-next.
regards
Stefan Schmidt
The following changes since commit b9f1f1ce866c28e3d9b86202441b220244754a69:
tcp: fix tcp_xmit_retransmit_queue() after rbtree introduction (2017-10-18 14:19:26 +0100)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/sschmidt/wpan-next.git ieee802154-for-davem-2017-10-18
for you to fetch changes up to 396665e8320987ff43b20a62a6a1cdae57aa1cc1:
Merge remote-tracking branch 'net-next/master' (2017-10-18 17:40:18 +0200)
----------------------------------------------------------------
A warning fix from Colin King and a typo fix from Xue Liu. Bundled together with
a fixed firmware version check in the atusb driver.
----------------------------------------------------------------
Colin Ian King (1):
ieee802154: atusb: make two structures static, fixes warnings
Stefan Schmidt (2):
ieee802154: atusb: fix firmware version check to enable frame retries
Merge remote-tracking branch 'net-next/master'
Xue Liu (1):
ieee802154: netlink: fix typo of the name of struct genl_ops
drivers/net/ieee802154/atusb.c | 8 +++-----
net/ieee802154/netlink.c | 6 +++---
2 files changed, 6 insertions(+), 8 deletions(-)
^ 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