All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v2 0/6] gtp: misc improvements
@ 2017-01-30 16:37 Andreas Schultz
  2017-01-30 16:37 ` [PATCH net-next v2 1/6] gtp: make GTP sockets in gtp_newlink optional Andreas Schultz
                   ` (6 more replies)
  0 siblings, 7 replies; 29+ messages in thread
From: Andreas Schultz @ 2017-01-30 16:37 UTC (permalink / raw)
  To: Pablo Neira; +Cc: netdev, Harald Welte, Lionel Gauthier, openbsc

Hi Pablo,

Resent as v2, because I forgot the net-next target. Sorry for noise,
I promise I won't forget it again.

This series lays the groundwork for removing the socket references from
the GTP netdevice by removing duplicate code and simplifying the logic on
some code paths.

It slighly changes the GTP genl API by making the socket parameters optional
(though one of them is still required).

The removal of the socket references will break the 1:1 releation between
GTP netdevice and GTP socket that prevents us to support multiple VRFs with
overlaping IP addresse spaces attached to the same GTP socket (needed for
multi APN support).

Regards
Andreas


Andreas Schultz (6):
  gtp: make GTP sockets in gtp_newlink optional
  gtp: merge gtp_get_net and gtp_genl_find_dev
  gtp: unify genl_find_pdp and prepare for per socket lookup
  gtp: consolidate pdp context destruction into helper
  gtp: add socket to pdp context
  gtp: consolidate gtp socket rx path

 drivers/net/gtp.c | 564 +++++++++++++++++++++++++++---------------------------
 1 file changed, 280 insertions(+), 284 deletions(-)

-- 
2.10.2

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH net-next v2 1/6] gtp: make GTP sockets in gtp_newlink optional
  2017-01-30 16:37 [PATCH net-next v2 0/6] gtp: misc improvements Andreas Schultz
@ 2017-01-30 16:37 ` Andreas Schultz
  2017-02-02 14:10   ` Pablo Neira Ayuso
  2017-02-06 13:51   ` Harald Welte
  2017-01-30 16:37 ` [PATCH net-next v2 2/6] gtp: merge gtp_get_net and gtp_genl_find_dev Andreas Schultz
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 29+ messages in thread
From: Andreas Schultz @ 2017-01-30 16:37 UTC (permalink / raw)
  To: Pablo Neira; +Cc: netdev, Harald Welte, Lionel Gauthier, openbsc

Having both GTPv0-U and GTPv1-U is not always desirable.
Fallback from GTPv1-U to GTPv0-U was depreciated from 3GPP
Rel-8 onwards. Post Rel-8 implementation are discuraged
from listening on the v0 port (see 3GPP TS 29.281, Sect. 1).

A future change will completely decouple the sockets from the
network device. Till then, at least one of the sockets needs to
be specified (either v0 or v1), the other is optional.

Signed-off-by: Andreas Schultz <aschultz@tpip.net>
---
 drivers/net/gtp.c | 142 +++++++++++++++++++++++++++++-------------------------
 1 file changed, 76 insertions(+), 66 deletions(-)

diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index bda0c64..18944f4 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -259,28 +259,30 @@ static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb,
 	return iptunnel_pull_header(skb, hdrlen, skb->protocol, xnet);
 }
 
-static void gtp_encap_disable(struct gtp_dev *gtp)
-{
-	if (gtp->sock0 && gtp->sock0->sk) {
-		udp_sk(gtp->sock0->sk)->encap_type = 0;
-		rcu_assign_sk_user_data(gtp->sock0->sk, NULL);
-	}
-	if (gtp->sock1u && gtp->sock1u->sk) {
-		udp_sk(gtp->sock1u->sk)->encap_type = 0;
-		rcu_assign_sk_user_data(gtp->sock1u->sk, NULL);
-	}
-
-	gtp->sock0 = NULL;
-	gtp->sock1u = NULL;
-}
-
 static void gtp_encap_destroy(struct sock *sk)
 {
 	struct gtp_dev *gtp;
 
 	gtp = rcu_dereference_sk_user_data(sk);
-	if (gtp)
-		gtp_encap_disable(gtp);
+	if (gtp) {
+		udp_sk(sk)->encap_type = 0;
+		rcu_assign_sk_user_data(sk, NULL);
+	}
+}
+
+static void gtp_encap_disable_sock(struct socket *sock)
+{
+	if (!sock || !sock->sk)
+		return;
+
+	gtp_encap_destroy(sock->sk);
+	sockfd_put(sock);
+}
+
+static void gtp_encap_disable(struct gtp_dev *gtp)
+{
+	gtp_encap_disable_sock(gtp->sock0);
+	gtp_encap_disable_sock(gtp->sock1u);
 }
 
 /* UDP encapsulation receive handler. See net/ipv4/udp.c.
@@ -640,27 +642,24 @@ 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 net_device *dev, struct gtp_dev *gtp,
-			    int fd_gtp0, int fd_gtp1);
+static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[]);
+static void gtp_encap_disable(struct gtp_dev *gtp);
 
 static int gtp_newlink(struct net *src_net, struct net_device *dev,
 			struct nlattr *tb[], struct nlattr *data[])
 {
-	int hashsize, err, fd0, fd1;
+	int hashsize, err;
 	struct gtp_dev *gtp;
 	struct gtp_net *gn;
 
-	if (!data[IFLA_GTP_FD0] || !data[IFLA_GTP_FD1])
+	if (!data[IFLA_GTP_FD0] && !data[IFLA_GTP_FD1])
 		return -EINVAL;
 
 	gtp = netdev_priv(dev);
 
-	fd0 = nla_get_u32(data[IFLA_GTP_FD0]);
-	fd1 = nla_get_u32(data[IFLA_GTP_FD1]);
-
-	err = gtp_encap_enable(dev, gtp, fd0, fd1);
+	err = gtp_encap_enable(gtp, data);
 	if (err < 0)
-		goto out_err;
+		return err;
 
 	if (!data[IFLA_GTP_PDP_HASHSIZE])
 		hashsize = 1024;
@@ -688,7 +687,6 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
 	gtp_hashtable_free(gtp);
 out_encap:
 	gtp_encap_disable(gtp);
-out_err:
 	return err;
 }
 
@@ -803,61 +801,73 @@ static void gtp_hashtable_free(struct gtp_dev *gtp)
 	kfree(gtp->tid_hash);
 }
 
-static int gtp_encap_enable(struct net_device *dev, struct gtp_dev *gtp,
-			    int fd_gtp0, int fd_gtp1)
+static struct socket *gtp_encap_enable_socket(int fd, int type,
+					      struct gtp_dev *gtp)
 {
 	struct udp_tunnel_sock_cfg tuncfg = {NULL};
-	struct socket *sock0, *sock1u;
+	struct socket *sock;
 	int err;
 
-	netdev_dbg(dev, "enable gtp on %d, %d\n", fd_gtp0, fd_gtp1);
+	pr_debug("enable gtp on %d, %d\n", fd, type);
 
-	sock0 = sockfd_lookup(fd_gtp0, &err);
-	if (sock0 == NULL) {
-		netdev_dbg(dev, "socket fd=%d not found (gtp0)\n", fd_gtp0);
-		return -ENOENT;
+	sock = sockfd_lookup(fd, &err);
+	if (!sock) {
+		pr_debug("gtp socket fd=%d not found\n", fd);
+		return NULL;
 	}
 
-	if (sock0->sk->sk_protocol != IPPROTO_UDP) {
-		netdev_dbg(dev, "socket fd=%d not UDP\n", fd_gtp0);
+	if (sock->sk->sk_protocol != IPPROTO_UDP) {
+		pr_debug("socket fd=%d not UDP\n", fd);
 		err = -EINVAL;
-		goto err1;
+		goto out_sock;
 	}
 
-	sock1u = sockfd_lookup(fd_gtp1, &err);
-	if (sock1u == NULL) {
-		netdev_dbg(dev, "socket fd=%d not found (gtp1u)\n", fd_gtp1);
-		err = -ENOENT;
-		goto err1;
+	if (rcu_dereference_sk_user_data(sock->sk)) {
+		err = -EBUSY;
+		goto out_sock;
 	}
 
-	if (sock1u->sk->sk_protocol != IPPROTO_UDP) {
-		netdev_dbg(dev, "socket fd=%d not UDP\n", fd_gtp1);
-		err = -EINVAL;
-		goto err2;
-	}
-
-	netdev_dbg(dev, "enable gtp on %p, %p\n", sock0, sock1u);
-
-	gtp->sock0 = sock0;
-	gtp->sock1u = sock1u;
-
 	tuncfg.sk_user_data = gtp;
+	tuncfg.encap_type = type;
 	tuncfg.encap_rcv = gtp_encap_recv;
 	tuncfg.encap_destroy = gtp_encap_destroy;
 
-	tuncfg.encap_type = UDP_ENCAP_GTP0;
-	setup_udp_tunnel_sock(sock_net(gtp->sock0->sk), gtp->sock0, &tuncfg);
-
-	tuncfg.encap_type = UDP_ENCAP_GTP1U;
-	setup_udp_tunnel_sock(sock_net(gtp->sock1u->sk), gtp->sock1u, &tuncfg);
-
-	err = 0;
-err2:
-	sockfd_put(sock1u);
-err1:
-	sockfd_put(sock0);
-	return err;
+	setup_udp_tunnel_sock(sock_net(sock->sk), sock, &tuncfg);
+	return sock;
+
+out_sock:
+	sockfd_put(sock);
+	return ERR_PTR(err);
+}
+
+static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[])
+{
+	struct socket *sock0 = NULL;
+	struct socket *sock1u = NULL;
+
+	if (data[IFLA_GTP_FD0]) {
+		u32 fd0 = nla_get_u32(data[IFLA_GTP_FD0]);
+
+		sock0 = gtp_encap_enable_socket(fd0, UDP_ENCAP_GTP0, gtp);
+		if (IS_ERR(sock0))
+			return PTR_ERR(sock0);
+	}
+
+	if (data[IFLA_GTP_FD1]) {
+		u32 fd1 = nla_get_u32(data[IFLA_GTP_FD1]);
+
+		sock1u = gtp_encap_enable_socket(fd1, UDP_ENCAP_GTP1U, gtp);
+		if (IS_ERR(sock1u)) {
+			if (sock0)
+				sockfd_put(sock0);
+			return PTR_ERR(sock1u);
+		}
+	}
+
+	gtp->sock0 = sock0;
+	gtp->sock1u = sock1u;
+
+	return 0;
 }
 
 static struct net_device *gtp_find_dev(struct net *net, int ifindex)
-- 
2.10.2

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH net-next v2 2/6] gtp: merge gtp_get_net and gtp_genl_find_dev
  2017-01-30 16:37 [PATCH net-next v2 0/6] gtp: misc improvements Andreas Schultz
  2017-01-30 16:37 ` [PATCH net-next v2 1/6] gtp: make GTP sockets in gtp_newlink optional Andreas Schultz
@ 2017-01-30 16:37 ` Andreas Schultz
  2017-02-06 13:55   ` Harald Welte
  2017-01-30 16:37 ` [PATCH net-next v2 3/6] gtp: unify genl_find_pdp and prepare for per socket lookup Andreas Schultz
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 29+ messages in thread
From: Andreas Schultz @ 2017-01-30 16:37 UTC (permalink / raw)
  To: Pablo Neira; +Cc: netdev, Harald Welte, Lionel Gauthier, openbsc

Both function are always used together with the final goal to
get the gtp_dev. This simplifies the code by merging them together.

The netdevice lookup is changed to use the regular dev_get_by_index.
The gtp netdevice list is now only used to find the PDP contexts for
imcomming packets. It can be completely eliminated Once the TEID
hash is moved into the GTP socket.

Signed-off-by: Andreas Schultz <aschultz@tpip.net>
---
 drivers/net/gtp.c | 170 ++++++++++++++++++++++++++----------------------------
 1 file changed, 81 insertions(+), 89 deletions(-)

diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 18944f4..c96c71f 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -745,21 +745,6 @@ static struct rtnl_link_ops gtp_link_ops __read_mostly = {
 	.fill_info	= gtp_fill_info,
 };
 
-static struct net *gtp_genl_get_net(struct net *src_net, struct nlattr *tb[])
-{
-	struct net *net;
-
-	/* Examine the link attributes and figure out which network namespace
-	 * we are talking about.
-	 */
-	if (tb[GTPA_NET_NS_FD])
-		net = get_net_ns_by_fd(nla_get_u32(tb[GTPA_NET_NS_FD]));
-	else
-		net = get_net(src_net);
-
-	return net;
-}
-
 static int gtp_hashtable_new(struct gtp_dev *gtp, int hsize)
 {
 	int i;
@@ -870,16 +855,31 @@ static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[])
 	return 0;
 }
 
-static struct net_device *gtp_find_dev(struct net *net, int ifindex)
+static struct gtp_dev *gtp_genl_find_dev(struct net *src_net,
+					 struct nlattr *tb[])
 {
-	struct gtp_net *gn = net_generic(net, gtp_net_id);
-	struct gtp_dev *gtp;
-
-	list_for_each_entry_rcu(gtp, &gn->gtp_dev_list, list) {
-		if (ifindex == gtp->dev->ifindex)
-			return gtp->dev;
-	}
-	return NULL;
+	struct net *net;
+	struct net_device *dev;
+	struct gtp_dev *gtp = NULL;
+
+	/* Examine the link attributes and figure out which network namespace
+	 * we are talking about.
+	 */
+	if (tb[GTPA_NET_NS_FD])
+		net = get_net_ns_by_fd(nla_get_u32(tb[GTPA_NET_NS_FD]));
+	else
+		net = get_net(src_net);
+
+	if (IS_ERR(net))
+		return NULL;
+
+	/* Check if there's an existing gtpX device to configure */
+	dev = dev_get_by_index_rcu(net, nla_get_u32(tb[GTPA_LINK]));
+	if (dev->netdev_ops == &gtp_netdev_ops)
+		gtp = netdev_priv(dev);
+
+	put_net(net);
+	return gtp;
 }
 
 static void ipv4_pdp_fill(struct pdp_ctx *pctx, struct genl_info *info)
@@ -909,9 +909,8 @@ static void ipv4_pdp_fill(struct pdp_ctx *pctx, struct genl_info *info)
 	}
 }
 
-static int ipv4_pdp_add(struct net_device *dev, struct genl_info *info)
+static int ipv4_pdp_add(struct gtp_dev *gtp, struct genl_info *info)
 {
-	struct gtp_dev *gtp = netdev_priv(dev);
 	u32 hash_ms, hash_tid = 0;
 	struct pdp_ctx *pctx;
 	bool found = false;
@@ -936,11 +935,11 @@ static int ipv4_pdp_add(struct net_device *dev, struct genl_info *info)
 		ipv4_pdp_fill(pctx, info);
 
 		if (pctx->gtp_version == GTP_V0)
-			netdev_dbg(dev, "GTPv0-U: update tunnel id = %llx (pdp %p)\n",
-				   pctx->u.v0.tid, pctx);
+			pr_debug("GTPv0-U: update tunnel id = %llx (pdp %p)\n",
+				 pctx->u.v0.tid, pctx);
 		else if (pctx->gtp_version == GTP_V1)
-			netdev_dbg(dev, "GTPv1-U: update tunnel id = %x/%x (pdp %p)\n",
-				   pctx->u.v1.i_tei, pctx->u.v1.o_tei, pctx);
+			pr_debug("GTPv1-U: update tunnel id = %x/%x (pdp %p)\n",
+				 pctx->u.v1.i_tei, pctx->u.v1.o_tei, pctx);
 
 		return 0;
 
@@ -972,14 +971,14 @@ static int ipv4_pdp_add(struct net_device *dev, struct genl_info *info)
 
 	switch (pctx->gtp_version) {
 	case GTP_V0:
-		netdev_dbg(dev, "GTPv0-U: new PDP ctx id=%llx ssgn=%pI4 ms=%pI4 (pdp=%p)\n",
-			   pctx->u.v0.tid, &pctx->sgsn_addr_ip4,
-			   &pctx->ms_addr_ip4, pctx);
+		pr_debug("GTPv0-U: new PDP ctx id=%llx ssgn=%pI4 ms=%pI4 (pdp=%p)\n",
+			 pctx->u.v0.tid, &pctx->sgsn_addr_ip4,
+			 &pctx->ms_addr_ip4, pctx);
 		break;
 	case GTP_V1:
-		netdev_dbg(dev, "GTPv1-U: new PDP ctx id=%x/%x ssgn=%pI4 ms=%pI4 (pdp=%p)\n",
-			   pctx->u.v1.i_tei, pctx->u.v1.o_tei,
-			   &pctx->sgsn_addr_ip4, &pctx->ms_addr_ip4, pctx);
+		pr_debug("GTPv1-U: new PDP ctx id=%x/%x ssgn=%pI4 ms=%pI4 (pdp=%p)\n",
+			 pctx->u.v1.i_tei, pctx->u.v1.o_tei,
+			 &pctx->sgsn_addr_ip4, &pctx->ms_addr_ip4, pctx);
 		break;
 	}
 
@@ -988,8 +987,8 @@ static int ipv4_pdp_add(struct net_device *dev, struct genl_info *info)
 
 static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info)
 {
-	struct net_device *dev;
-	struct net *net;
+	struct gtp_dev *gtp;
+	int err;
 
 	if (!info->attrs[GTPA_VERSION] ||
 	    !info->attrs[GTPA_LINK] ||
@@ -1013,77 +1012,79 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info)
 		return -EINVAL;
 	}
 
-	net = gtp_genl_get_net(sock_net(skb->sk), info->attrs);
-	if (IS_ERR(net))
-		return PTR_ERR(net);
+	rcu_read_lock();
 
-	/* Check if there's an existing gtpX device to configure */
-	dev = gtp_find_dev(net, nla_get_u32(info->attrs[GTPA_LINK]));
-	if (dev == NULL) {
-		put_net(net);
-		return -ENODEV;
+	gtp = gtp_genl_find_dev(sock_net(skb->sk), info->attrs);
+	if (!gtp) {
+		err = -ENODEV;
+		goto out_unlock;
 	}
-	put_net(net);
 
-	return ipv4_pdp_add(dev, info);
+	err = ipv4_pdp_add(gtp, info);
+
+out_unlock:
+	rcu_read_unlock();
+	return err;
 }
 
 static int gtp_genl_del_pdp(struct sk_buff *skb, struct genl_info *info)
 {
-	struct net_device *dev;
 	struct pdp_ctx *pctx;
 	struct gtp_dev *gtp;
-	struct net *net;
+	int err = 0;
 
 	if (!info->attrs[GTPA_VERSION] ||
 	    !info->attrs[GTPA_LINK])
 		return -EINVAL;
 
-	net = gtp_genl_get_net(sock_net(skb->sk), info->attrs);
-	if (IS_ERR(net))
-		return PTR_ERR(net);
+	rcu_read_lock();
 
-	/* Check if there's an existing gtpX device to configure */
-	dev = gtp_find_dev(net, nla_get_u32(info->attrs[GTPA_LINK]));
-	if (dev == NULL) {
-		put_net(net);
-		return -ENODEV;
+	gtp = gtp_genl_find_dev(sock_net(skb->sk), info->attrs);
+	if (!gtp) {
+		err = -ENODEV;
+		goto out_unlock;
 	}
-	put_net(net);
-
-	gtp = netdev_priv(dev);
 
 	switch (nla_get_u32(info->attrs[GTPA_VERSION])) {
 	case GTP_V0:
-		if (!info->attrs[GTPA_TID])
-			return -EINVAL;
+		if (!info->attrs[GTPA_TID]) {
+			err = -EINVAL;
+			goto out_unlock;
+		}
 		pctx = gtp0_pdp_find(gtp, nla_get_u64(info->attrs[GTPA_TID]));
 		break;
 	case GTP_V1:
-		if (!info->attrs[GTPA_I_TEI])
-			return -EINVAL;
+		if (!info->attrs[GTPA_I_TEI]) {
+			err = -EINVAL;
+			goto out_unlock;
+		}
 		pctx = gtp1_pdp_find(gtp, nla_get_u64(info->attrs[GTPA_I_TEI]));
 		break;
 
 	default:
-		return -EINVAL;
+		err = -EINVAL;
+		goto out_unlock;
 	}
 
-	if (pctx == NULL)
-		return -ENOENT;
+	if (!pctx) {
+		err = -ENOENT;
+		goto out_unlock;
+	}
 
 	if (pctx->gtp_version == GTP_V0)
-		netdev_dbg(dev, "GTPv0-U: deleting tunnel id = %llx (pdp %p)\n",
-			   pctx->u.v0.tid, pctx);
+		pr_debug("GTPv0-U: deleting tunnel id = %llx (pdp %p)\n",
+			 pctx->u.v0.tid, pctx);
 	else if (pctx->gtp_version == GTP_V1)
-		netdev_dbg(dev, "GTPv1-U: deleting tunnel id = %x/%x (pdp %p)\n",
-			   pctx->u.v1.i_tei, pctx->u.v1.o_tei, pctx);
+		pr_debug("GTPv1-U: deleting tunnel id = %x/%x (pdp %p)\n",
+			 pctx->u.v1.i_tei, pctx->u.v1.o_tei, pctx);
 
 	hlist_del_rcu(&pctx->hlist_tid);
 	hlist_del_rcu(&pctx->hlist_addr);
 	kfree_rcu(pctx, rcu_head);
 
-	return 0;
+out_unlock:
+	rcu_read_unlock();
+	return err;
 }
 
 static struct genl_family gtp_genl_family;
@@ -1127,11 +1128,9 @@ static int gtp_genl_fill_info(struct sk_buff *skb, u32 snd_portid, u32 snd_seq,
 static int gtp_genl_get_pdp(struct sk_buff *skb, struct genl_info *info)
 {
 	struct pdp_ctx *pctx = NULL;
-	struct net_device *dev;
 	struct sk_buff *skb2;
 	struct gtp_dev *gtp;
 	u32 gtp_version;
-	struct net *net;
 	int err;
 
 	if (!info->attrs[GTPA_VERSION] ||
@@ -1147,21 +1146,14 @@ static int gtp_genl_get_pdp(struct sk_buff *skb, struct genl_info *info)
 		return -EINVAL;
 	}
 
-	net = gtp_genl_get_net(sock_net(skb->sk), info->attrs);
-	if (IS_ERR(net))
-		return PTR_ERR(net);
-
-	/* Check if there's an existing gtpX device to configure */
-	dev = gtp_find_dev(net, nla_get_u32(info->attrs[GTPA_LINK]));
-	if (dev == NULL) {
-		put_net(net);
-		return -ENODEV;
-	}
-	put_net(net);
-
-	gtp = netdev_priv(dev);
-
 	rcu_read_lock();
+
+	gtp = gtp_genl_find_dev(sock_net(skb->sk), info->attrs);
+	if (!gtp) {
+		err = -ENODEV;
+		goto err_unlock;
+	}
+
 	if (gtp_version == GTP_V0 &&
 	    info->attrs[GTPA_TID]) {
 		u64 tid = nla_get_u64(info->attrs[GTPA_TID]);
-- 
2.10.2

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH net-next v2 3/6] gtp: unify genl_find_pdp and prepare for per socket lookup
  2017-01-30 16:37 [PATCH net-next v2 0/6] gtp: misc improvements Andreas Schultz
  2017-01-30 16:37 ` [PATCH net-next v2 1/6] gtp: make GTP sockets in gtp_newlink optional Andreas Schultz
  2017-01-30 16:37 ` [PATCH net-next v2 2/6] gtp: merge gtp_get_net and gtp_genl_find_dev Andreas Schultz
@ 2017-01-30 16:37 ` Andreas Schultz
  2017-02-02 14:19   ` Pablo Neira Ayuso
  2017-02-06 13:56   ` Harald Welte
  2017-01-30 16:37 ` [PATCH net-next v2 4/6] gtp: consolidate pdp context destruction into helper Andreas Schultz
                   ` (3 subsequent siblings)
  6 siblings, 2 replies; 29+ messages in thread
From: Andreas Schultz @ 2017-01-30 16:37 UTC (permalink / raw)
  To: Pablo Neira; +Cc: netdev, Harald Welte, Lionel Gauthier, openbsc

This unifies duplicate code into a helper. It also prepares the
groundwork to add a lookup version that uses the socket to find
attache pdp contexts.

Signed-off-by: Andreas Schultz <aschultz@tpip.net>
---
 drivers/net/gtp.c | 120 +++++++++++++++++++++++-------------------------------
 1 file changed, 51 insertions(+), 69 deletions(-)

diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index c96c71f..6b7a3c2 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -1027,47 +1027,62 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info)
 	return err;
 }
 
+static struct pdp_ctx *gtp_genl_find_pdp_by_link(struct sk_buff *skb,
+						 struct genl_info *info)
+{
+	struct gtp_dev *gtp;
+
+	gtp = gtp_genl_find_dev(sock_net(skb->sk), info->attrs);
+	if (!gtp)
+		return ERR_PTR(-ENODEV);
+
+	if (info->attrs[GTPA_MS_ADDRESS]) {
+		__be32 ip = nla_get_be32(info->attrs[GTPA_MS_ADDRESS]);
+
+		return ipv4_pdp_find(gtp, ip);
+	} else if (info->attrs[GTPA_VERSION]) {
+		u32 gtp_version = nla_get_u32(info->attrs[GTPA_VERSION]);
+
+		if (gtp_version == GTP_V0 && info->attrs[GTPA_TID])
+			return gtp0_pdp_find(gtp, nla_get_u64(
+						     info->attrs[GTPA_TID]));
+		else if (gtp_version == GTP_V1 && info->attrs[GTPA_I_TEI])
+			return gtp1_pdp_find(gtp, nla_get_u32(
+						     info->attrs[GTPA_I_TEI]));
+	}
+
+	return ERR_PTR(-EINVAL);
+}
+
+static struct pdp_ctx *gtp_genl_find_pdp(struct sk_buff *skb,
+					 struct genl_info *info)
+{
+	struct pdp_ctx *pctx;
+
+	if (info->attrs[GTPA_LINK])
+		pctx = gtp_genl_find_pdp_by_link(skb, info);
+	else
+		pctx = ERR_PTR(-EINVAL);
+
+	if (!pctx)
+		pctx = ERR_PTR(-ENOENT);
+
+	return pctx;
+}
+
 static int gtp_genl_del_pdp(struct sk_buff *skb, struct genl_info *info)
 {
 	struct pdp_ctx *pctx;
-	struct gtp_dev *gtp;
 	int err = 0;
 
-	if (!info->attrs[GTPA_VERSION] ||
-	    !info->attrs[GTPA_LINK])
+	if (!info->attrs[GTPA_VERSION])
 		return -EINVAL;
 
 	rcu_read_lock();
 
-	gtp = gtp_genl_find_dev(sock_net(skb->sk), info->attrs);
-	if (!gtp) {
-		err = -ENODEV;
-		goto out_unlock;
-	}
-
-	switch (nla_get_u32(info->attrs[GTPA_VERSION])) {
-	case GTP_V0:
-		if (!info->attrs[GTPA_TID]) {
-			err = -EINVAL;
-			goto out_unlock;
-		}
-		pctx = gtp0_pdp_find(gtp, nla_get_u64(info->attrs[GTPA_TID]));
-		break;
-	case GTP_V1:
-		if (!info->attrs[GTPA_I_TEI]) {
-			err = -EINVAL;
-			goto out_unlock;
-		}
-		pctx = gtp1_pdp_find(gtp, nla_get_u64(info->attrs[GTPA_I_TEI]));
-		break;
-
-	default:
-		err = -EINVAL;
-		goto out_unlock;
-	}
-
-	if (!pctx) {
-		err = -ENOENT;
+	pctx = gtp_genl_find_pdp(skb, info);
+	if (IS_ERR(pctx)) {
+		err = PTR_ERR(pctx);
 		goto out_unlock;
 	}
 
@@ -1129,49 +1144,16 @@ static int gtp_genl_get_pdp(struct sk_buff *skb, struct genl_info *info)
 {
 	struct pdp_ctx *pctx = NULL;
 	struct sk_buff *skb2;
-	struct gtp_dev *gtp;
-	u32 gtp_version;
 	int err;
 
-	if (!info->attrs[GTPA_VERSION] ||
-	    !info->attrs[GTPA_LINK])
+	if (!info->attrs[GTPA_VERSION])
 		return -EINVAL;
 
-	gtp_version = nla_get_u32(info->attrs[GTPA_VERSION]);
-	switch (gtp_version) {
-	case GTP_V0:
-	case GTP_V1:
-		break;
-	default:
-		return -EINVAL;
-	}
-
 	rcu_read_lock();
 
-	gtp = gtp_genl_find_dev(sock_net(skb->sk), info->attrs);
-	if (!gtp) {
-		err = -ENODEV;
-		goto err_unlock;
-	}
-
-	if (gtp_version == GTP_V0 &&
-	    info->attrs[GTPA_TID]) {
-		u64 tid = nla_get_u64(info->attrs[GTPA_TID]);
-
-		pctx = gtp0_pdp_find(gtp, tid);
-	} else if (gtp_version == GTP_V1 &&
-		 info->attrs[GTPA_I_TEI]) {
-		u32 tid = nla_get_u32(info->attrs[GTPA_I_TEI]);
-
-		pctx = gtp1_pdp_find(gtp, tid);
-	} else if (info->attrs[GTPA_MS_ADDRESS]) {
-		__be32 ip = nla_get_be32(info->attrs[GTPA_MS_ADDRESS]);
-
-		pctx = ipv4_pdp_find(gtp, ip);
-	}
-
-	if (pctx == NULL) {
-		err = -ENOENT;
+	pctx = gtp_genl_find_pdp(skb, info);
+	if (IS_ERR(pctx)) {
+		err = PTR_ERR(pctx);
 		goto err_unlock;
 	}
 
-- 
2.10.2

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH net-next v2 4/6] gtp: consolidate pdp context destruction into helper
  2017-01-30 16:37 [PATCH net-next v2 0/6] gtp: misc improvements Andreas Schultz
                   ` (2 preceding siblings ...)
  2017-01-30 16:37 ` [PATCH net-next v2 3/6] gtp: unify genl_find_pdp and prepare for per socket lookup Andreas Schultz
@ 2017-01-30 16:37 ` Andreas Schultz
  2017-02-06 13:58   ` Harald Welte
  2017-01-30 16:37 ` [PATCH net-next v2 5/6] gtp: add socket to pdp context Andreas Schultz
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 29+ messages in thread
From: Andreas Schultz @ 2017-01-30 16:37 UTC (permalink / raw)
  To: Pablo Neira; +Cc: netdev, Harald Welte, Lionel Gauthier, openbsc

Consolidate duplicate code into helper.

Signed-off-by: Andreas Schultz <aschultz@tpip.net>
---
 drivers/net/gtp.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 6b7a3c2..68c6c9b 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -84,6 +84,8 @@ struct gtp_net {
 
 static u32 gtp_h_initval;
 
+static void pdp_context_delete(struct pdp_ctx *pctx);
+
 static inline u32 gtp0_hashfn(u64 tid)
 {
 	u32 *tid32 = (u32 *) &tid;
@@ -774,13 +776,10 @@ static void gtp_hashtable_free(struct gtp_dev *gtp)
 	struct pdp_ctx *pctx;
 	int i;
 
-	for (i = 0; i < gtp->hash_size; i++) {
-		hlist_for_each_entry_rcu(pctx, &gtp->tid_hash[i], hlist_tid) {
-			hlist_del_rcu(&pctx->hlist_tid);
-			hlist_del_rcu(&pctx->hlist_addr);
-			kfree_rcu(pctx, rcu_head);
-		}
-	}
+	for (i = 0; i < gtp->hash_size; i++)
+		hlist_for_each_entry_rcu(pctx, &gtp->tid_hash[i], hlist_tid)
+			pdp_context_delete(pctx);
+
 	synchronize_rcu();
 	kfree(gtp->addr_hash);
 	kfree(gtp->tid_hash);
@@ -985,6 +984,13 @@ static int ipv4_pdp_add(struct gtp_dev *gtp, struct genl_info *info)
 	return 0;
 }
 
+static void pdp_context_delete(struct pdp_ctx *pctx)
+{
+	hlist_del_rcu(&pctx->hlist_tid);
+	hlist_del_rcu(&pctx->hlist_addr);
+	kfree(pctx);
+}
+
 static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info)
 {
 	struct gtp_dev *gtp;
@@ -1093,9 +1099,7 @@ static int gtp_genl_del_pdp(struct sk_buff *skb, struct genl_info *info)
 		pr_debug("GTPv1-U: deleting tunnel id = %x/%x (pdp %p)\n",
 			 pctx->u.v1.i_tei, pctx->u.v1.o_tei, pctx);
 
-	hlist_del_rcu(&pctx->hlist_tid);
-	hlist_del_rcu(&pctx->hlist_addr);
-	kfree_rcu(pctx, rcu_head);
+	pdp_context_delete(pctx);
 
 out_unlock:
 	rcu_read_unlock();
-- 
2.10.2

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH net-next v2 5/6] gtp: add socket to pdp context
  2017-01-30 16:37 [PATCH net-next v2 0/6] gtp: misc improvements Andreas Schultz
                   ` (3 preceding siblings ...)
  2017-01-30 16:37 ` [PATCH net-next v2 4/6] gtp: consolidate pdp context destruction into helper Andreas Schultz
@ 2017-01-30 16:37 ` Andreas Schultz
  2017-02-02 13:56   ` Pablo Neira Ayuso
  2017-01-30 16:37 ` [PATCH net-next v2 6/6] gtp: consolidate gtp socket rx path Andreas Schultz
  2017-01-31 18:05 ` [PATCH net-next v2 0/6] gtp: misc improvements David Miller
  6 siblings, 1 reply; 29+ messages in thread
From: Andreas Schultz @ 2017-01-30 16:37 UTC (permalink / raw)
  To: Pablo Neira; +Cc: netdev, Harald Welte, Lionel Gauthier, openbsc

Having the socket present in context simplifies the sending logic.
It also fixes the invalid assumption that we have to use the same
sending socket for all client IP's on a specific gtp interface.

Signed-off-by: Andreas Schultz <aschultz@tpip.net>
---
 drivers/net/gtp.c | 72 ++++++++++++++++++++++++++++++-------------------------
 1 file changed, 39 insertions(+), 33 deletions(-)

diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 68c6c9b..ff00597 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -58,6 +58,8 @@ struct pdp_ctx {
 	struct in_addr		ms_addr_ip4;
 	struct in_addr		sgsn_addr_ip4;
 
+	struct sock		*sk;
+
 	atomic_t		tx_seq;
 	struct rcu_head		rcu_head;
 };
@@ -371,8 +373,9 @@ static void gtp_dev_uninit(struct net_device *dev)
 	free_percpu(dev->tstats);
 }
 
-static struct rtable *ip4_route_output_gtp(struct net *net, struct flowi4 *fl4,
-					   const struct sock *sk, __be32 daddr)
+static struct rtable *ip4_route_output_gtp(struct flowi4 *fl4,
+					   const struct sock *sk,
+					   __be32 daddr)
 {
 	memset(fl4, 0, sizeof(*fl4));
 	fl4->flowi4_oif		= sk->sk_bound_dev_if;
@@ -381,7 +384,7 @@ static struct rtable *ip4_route_output_gtp(struct net *net, struct flowi4 *fl4,
 	fl4->flowi4_tos		= RT_CONN_FLAGS(sk);
 	fl4->flowi4_proto	= sk->sk_protocol;
 
-	return ip_route_output_key(net, fl4);
+	return ip_route_output_key(sock_net(sk), fl4);
 }
 
 static inline void gtp0_push_header(struct sk_buff *skb, struct pdp_ctx *pctx)
@@ -470,7 +473,6 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct net_device *dev,
 	struct rtable *rt;
 	struct flowi4 fl4;
 	struct iphdr *iph;
-	struct sock *sk;
 	__be16 df;
 	int mtu;
 
@@ -486,30 +488,7 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct net_device *dev,
 	}
 	netdev_dbg(dev, "found PDP context %p\n", pctx);
 
-	switch (pctx->gtp_version) {
-	case GTP_V0:
-		if (gtp->sock0)
-			sk = gtp->sock0->sk;
-		else
-			sk = NULL;
-		break;
-	case GTP_V1:
-		if (gtp->sock1u)
-			sk = gtp->sock1u->sk;
-		else
-			sk = NULL;
-		break;
-	default:
-		return -ENOENT;
-	}
-
-	if (!sk) {
-		netdev_dbg(dev, "no userspace socket is available, skip\n");
-		return -ENOENT;
-	}
-
-	rt = ip4_route_output_gtp(sock_net(sk), &fl4, gtp->sock0->sk,
-				  pctx->sgsn_addr_ip4.s_addr);
+	rt = ip4_route_output_gtp(&fl4, pctx->sk, pctx->sgsn_addr_ip4.s_addr);
 	if (IS_ERR(rt)) {
 		netdev_dbg(dev, "no route to SSGN %pI4\n",
 			   &pctx->sgsn_addr_ip4.s_addr);
@@ -554,7 +533,7 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct net_device *dev,
 		goto err_rt;
 	}
 
-	gtp_set_pktinfo_ipv4(pktinfo, sk, iph, pctx, rt, &fl4, dev);
+	gtp_set_pktinfo_ipv4(pktinfo, pctx->sk, iph, pctx, rt, &fl4, dev);
 	gtp_push_header(skb, pktinfo);
 
 	return 0;
@@ -908,7 +887,8 @@ static void ipv4_pdp_fill(struct pdp_ctx *pctx, struct genl_info *info)
 	}
 }
 
-static int ipv4_pdp_add(struct gtp_dev *gtp, struct genl_info *info)
+static int ipv4_pdp_add(struct gtp_dev *gtp, struct sock *sk,
+			struct genl_info *info)
 {
 	u32 hash_ms, hash_tid = 0;
 	struct pdp_ctx *pctx;
@@ -948,6 +928,8 @@ static int ipv4_pdp_add(struct gtp_dev *gtp, struct genl_info *info)
 	if (pctx == NULL)
 		return -ENOMEM;
 
+	sock_hold(sk);
+	pctx->sk = sk;
 	ipv4_pdp_fill(pctx, info);
 	atomic_set(&pctx->tx_seq, 0);
 
@@ -984,16 +966,26 @@ static int ipv4_pdp_add(struct gtp_dev *gtp, struct genl_info *info)
 	return 0;
 }
 
+static void pdp_context_free(struct rcu_head *head)
+{
+	struct pdp_ctx *pctx = container_of(head, struct pdp_ctx, rcu_head);
+
+	sock_put(pctx->sk);
+	kfree(pctx);
+}
+
 static void pdp_context_delete(struct pdp_ctx *pctx)
 {
 	hlist_del_rcu(&pctx->hlist_tid);
 	hlist_del_rcu(&pctx->hlist_addr);
-	kfree(pctx);
+	call_rcu(&pctx->rcu_head, pdp_context_free);
 }
 
 static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info)
 {
+	unsigned int version;
 	struct gtp_dev *gtp;
+	struct socket *sock;
 	int err;
 
 	if (!info->attrs[GTPA_VERSION] ||
@@ -1002,7 +994,9 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info)
 	    !info->attrs[GTPA_MS_ADDRESS])
 		return -EINVAL;
 
-	switch (nla_get_u32(info->attrs[GTPA_VERSION])) {
+	version = nla_get_u32(info->attrs[GTPA_VERSION]);
+
+	switch (version) {
 	case GTP_V0:
 		if (!info->attrs[GTPA_TID] ||
 		    !info->attrs[GTPA_FLOW])
@@ -1026,7 +1020,19 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info)
 		goto out_unlock;
 	}
 
-	err = ipv4_pdp_add(gtp, info);
+	if (version == GTP_V0)
+		sock = gtp->sock0;
+	else if (version == GTP_V1)
+		sock = gtp->sock1u;
+	else
+		sock = NULL;
+
+	if (!sock || !sock->sk) {
+		err = -ENODEV;
+		goto out_unlock;
+	}
+
+	err = ipv4_pdp_add(gtp, sock->sk, info);
 
 out_unlock:
 	rcu_read_unlock();
-- 
2.10.2

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH net-next v2 6/6] gtp: consolidate gtp socket rx path
  2017-01-30 16:37 [PATCH net-next v2 0/6] gtp: misc improvements Andreas Schultz
                   ` (4 preceding siblings ...)
  2017-01-30 16:37 ` [PATCH net-next v2 5/6] gtp: add socket to pdp context Andreas Schultz
@ 2017-01-30 16:37 ` Andreas Schultz
  2017-01-31 18:05 ` [PATCH net-next v2 0/6] gtp: misc improvements David Miller
  6 siblings, 0 replies; 29+ messages in thread
From: Andreas Schultz @ 2017-01-30 16:37 UTC (permalink / raw)
  To: Pablo Neira; +Cc: netdev, Harald Welte, Lionel Gauthier, openbsc

Add network device to gtp context in preparation for splitting
the TEID from the network device.

Use this to rework the socker rx path. Move the common RX part
of v0 and v1 into a helper. Also move the final rx part into
that helper as well.

Signed-off-by: Andreas Schultz <aschultz@tpip.net>
---
 drivers/net/gtp.c | 92 ++++++++++++++++++++++++++++---------------------------
 1 file changed, 47 insertions(+), 45 deletions(-)

diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index ff00597..9c31e83 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -58,6 +58,7 @@ struct pdp_ctx {
 	struct in_addr		ms_addr_ip4;
 	struct in_addr		sgsn_addr_ip4;
 
+	struct net_device       *dev;
 	struct sock		*sk;
 
 	atomic_t		tx_seq;
@@ -179,9 +180,42 @@ static bool gtp_check_src_ms(struct sk_buff *skb, struct pdp_ctx *pctx,
 	return false;
 }
 
+static int gtp_rx(struct sk_buff *skb, struct pdp_ctx *pctx, unsigned int hdrlen)
+{
+	struct pcpu_sw_netstats *stats;
+
+	if (!gtp_check_src_ms(skb, pctx, hdrlen)) {
+		pr_debug("No PDP ctx for this MS\n");
+		return 1;
+	}
+
+	/* Get rid of the GTP + UDP headers. */
+	if (iptunnel_pull_header(skb, hdrlen, skb->protocol,
+				 !net_eq(sock_net(pctx->sk), dev_net(pctx->dev))))
+		return -1;
+
+	pr_debug("forwarding packet from GGSN to uplink\n");
+
+	/* Now that the UDP and the GTP header have been removed, set up the
+	 * new network header. This is required by the upper layer to
+	 * calculate the transport header.
+	 */
+	skb_reset_network_header(skb);
+
+	skb->dev = pctx->dev;
+
+	stats = this_cpu_ptr(pctx->dev->tstats);
+	u64_stats_update_begin(&stats->syncp);
+	stats->rx_packets++;
+	stats->rx_bytes += skb->len;
+	u64_stats_update_end(&stats->syncp);
+
+	netif_rx(skb);
+	return 0;
+}
+
 /* 1 means pass up to the stack, -1 means drop and 0 means decapsulated. */
-static int gtp0_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb,
-			       bool xnet)
+static int gtp0_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb)
 {
 	unsigned int hdrlen = sizeof(struct udphdr) +
 			      sizeof(struct gtp0_header);
@@ -205,17 +239,10 @@ static int gtp0_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb,
 		return 1;
 	}
 
-	if (!gtp_check_src_ms(skb, pctx, hdrlen)) {
-		netdev_dbg(gtp->dev, "No PDP ctx for this MS\n");
-		return 1;
-	}
-
-	/* Get rid of the GTP + UDP headers. */
-	return iptunnel_pull_header(skb, hdrlen, skb->protocol, xnet);
+	return gtp_rx(skb, pctx, hdrlen);
 }
 
-static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb,
-				bool xnet)
+static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb)
 {
 	unsigned int hdrlen = sizeof(struct udphdr) +
 			      sizeof(struct gtp1_header);
@@ -254,13 +281,7 @@ static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb,
 		return 1;
 	}
 
-	if (!gtp_check_src_ms(skb, pctx, hdrlen)) {
-		netdev_dbg(gtp->dev, "No PDP ctx for this MS\n");
-		return 1;
-	}
-
-	/* Get rid of the GTP + UDP headers. */
-	return iptunnel_pull_header(skb, hdrlen, skb->protocol, xnet);
+	return gtp_rx(skb, pctx, hdrlen);
 }
 
 static void gtp_encap_destroy(struct sock *sk)
@@ -294,10 +315,8 @@ static void gtp_encap_disable(struct gtp_dev *gtp)
  */
 static int gtp_encap_recv(struct sock *sk, struct sk_buff *skb)
 {
-	struct pcpu_sw_netstats *stats;
 	struct gtp_dev *gtp;
-	bool xnet;
-	int ret;
+	int ret = 0;
 
 	gtp = rcu_dereference_sk_user_data(sk);
 	if (!gtp)
@@ -305,16 +324,14 @@ static int gtp_encap_recv(struct sock *sk, struct sk_buff *skb)
 
 	netdev_dbg(gtp->dev, "encap_recv sk=%p\n", sk);
 
-	xnet = !net_eq(sock_net(sk), dev_net(gtp->dev));
-
 	switch (udp_sk(sk)->encap_type) {
 	case UDP_ENCAP_GTP0:
 		netdev_dbg(gtp->dev, "received GTP0 packet\n");
-		ret = gtp0_udp_encap_recv(gtp, skb, xnet);
+		ret = gtp0_udp_encap_recv(gtp, skb);
 		break;
 	case UDP_ENCAP_GTP1U:
 		netdev_dbg(gtp->dev, "received GTP1U packet\n");
-		ret = gtp1u_udp_encap_recv(gtp, skb, xnet);
+		ret = gtp1u_udp_encap_recv(gtp, skb);
 		break;
 	default:
 		ret = -1; /* Shouldn't happen. */
@@ -323,33 +340,17 @@ static int gtp_encap_recv(struct sock *sk, struct sk_buff *skb)
 	switch (ret) {
 	case 1:
 		netdev_dbg(gtp->dev, "pass up to the process\n");
-		return 1;
+		break;
 	case 0:
-		netdev_dbg(gtp->dev, "forwarding packet from GGSN to uplink\n");
 		break;
 	case -1:
 		netdev_dbg(gtp->dev, "GTP packet has been dropped\n");
 		kfree_skb(skb);
-		return 0;
+		ret = 0;
+		break;
 	}
 
-	/* Now that the UDP and the GTP header have been removed, set up the
-	 * new network header. This is required by the upper layer to
-	 * calculate the transport header.
-	 */
-	skb_reset_network_header(skb);
-
-	skb->dev = gtp->dev;
-
-	stats = this_cpu_ptr(gtp->dev->tstats);
-	u64_stats_update_begin(&stats->syncp);
-	stats->rx_packets++;
-	stats->rx_bytes += skb->len;
-	u64_stats_update_end(&stats->syncp);
-
-	netif_rx(skb);
-
-	return 0;
+	return ret;
 }
 
 static int gtp_dev_init(struct net_device *dev)
@@ -930,6 +931,7 @@ static int ipv4_pdp_add(struct gtp_dev *gtp, struct sock *sk,
 
 	sock_hold(sk);
 	pctx->sk = sk;
+	pctx->dev = gtp->dev;
 	ipv4_pdp_fill(pctx, info);
 	atomic_set(&pctx->tx_seq, 0);
 
-- 
2.10.2

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 0/6] gtp: misc improvements
  2017-01-30 16:37 [PATCH net-next v2 0/6] gtp: misc improvements Andreas Schultz
                   ` (5 preceding siblings ...)
  2017-01-30 16:37 ` [PATCH net-next v2 6/6] gtp: consolidate gtp socket rx path Andreas Schultz
@ 2017-01-31 18:05 ` David Miller
  2017-02-06 13:46   ` Harald Welte
  6 siblings, 1 reply; 29+ messages in thread
From: David Miller @ 2017-01-31 18:05 UTC (permalink / raw)
  To: aschultz; +Cc: pablo, netdev, laforge, Lionel.Gauthier, openbsc

From: Andreas Schultz <aschultz@tpip.net>
Date: Mon, 30 Jan 2017 17:37:07 +0100

> Resent as v2, because I forgot the net-next target. Sorry for noise,
> I promise I won't forget it again.
> 
> This series lays the groundwork for removing the socket references from
> the GTP netdevice by removing duplicate code and simplifying the logic on
> some code paths.
> 
> It slighly changes the GTP genl API by making the socket parameters optional
> (though one of them is still required).
> 
> The removal of the socket references will break the 1:1 releation between
> GTP netdevice and GTP socket that prevents us to support multiple VRFs with
> overlaping IP addresse spaces attached to the same GTP socket (needed for
> multi APN support).

This series is being held up it is not being reviewed.

Please someone with GTP knowledge properly review this series.

Thank you.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 5/6] gtp: add socket to pdp context
  2017-01-30 16:37 ` [PATCH net-next v2 5/6] gtp: add socket to pdp context Andreas Schultz
@ 2017-02-02 13:56   ` Pablo Neira Ayuso
  2017-02-02 14:12     ` Andreas Schultz
  0 siblings, 1 reply; 29+ messages in thread
From: Pablo Neira Ayuso @ 2017-02-02 13:56 UTC (permalink / raw)
  To: Andreas Schultz; +Cc: netdev, Harald Welte, Lionel Gauthier, openbsc

On Mon, Jan 30, 2017 at 05:37:12PM +0100, Andreas Schultz wrote:
> Having the socket present in context simplifies the sending logic.
> It also fixes the invalid assumption that we have to use the same
> sending socket for all client IP's on a specific gtp interface.
> 
> Signed-off-by: Andreas Schultz <aschultz@tpip.net>
> ---
>  drivers/net/gtp.c | 72 ++++++++++++++++++++++++++++++-------------------------
>  1 file changed, 39 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
> index 68c6c9b..ff00597 100644
> --- a/drivers/net/gtp.c
> +++ b/drivers/net/gtp.c
[...]
> @@ -984,16 +966,26 @@ static int ipv4_pdp_add(struct gtp_dev *gtp, struct genl_info *info)
>  	return 0;
>  }
>  
> +static void pdp_context_free(struct rcu_head *head)
> +{
> +	struct pdp_ctx *pctx = container_of(head, struct pdp_ctx, rcu_head);
> +
> +	sock_put(pctx->sk);
> +	kfree(pctx);
> +}
> +
>  static void pdp_context_delete(struct pdp_ctx *pctx)
>  {
>  	hlist_del_rcu(&pctx->hlist_tid);
>  	hlist_del_rcu(&pctx->hlist_addr);
> -	kfree(pctx);
> +	call_rcu(&pctx->rcu_head, pdp_context_free);

This is fixing incorrect rcu conversion in 4/6. Please, fix this there.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 1/6] gtp: make GTP sockets in gtp_newlink optional
  2017-01-30 16:37 ` [PATCH net-next v2 1/6] gtp: make GTP sockets in gtp_newlink optional Andreas Schultz
@ 2017-02-02 14:10   ` Pablo Neira Ayuso
  2017-02-02 14:30     ` Andreas Schultz
  2017-02-06 13:51   ` Harald Welte
  1 sibling, 1 reply; 29+ messages in thread
From: Pablo Neira Ayuso @ 2017-02-02 14:10 UTC (permalink / raw)
  To: Andreas Schultz; +Cc: netdev, Harald Welte, Lionel Gauthier, openbsc

On Mon, Jan 30, 2017 at 05:37:08PM +0100, Andreas Schultz wrote:
> Having both GTPv0-U and GTPv1-U is not always desirable.
> Fallback from GTPv1-U to GTPv0-U was depreciated from 3GPP
> Rel-8 onwards. Post Rel-8 implementation are discuraged
> from listening on the v0 port (see 3GPP TS 29.281, Sect. 1).
> 
> A future change will completely decouple the sockets from the
> network device. Till then, at least one of the sockets needs to
> be specified (either v0 or v1), the other is optional.
> 
> Signed-off-by: Andreas Schultz <aschultz@tpip.net>
> ---
>  drivers/net/gtp.c | 142 +++++++++++++++++++++++++++++-------------------------
>  1 file changed, 76 insertions(+), 66 deletions(-)
> 
> diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
> index bda0c64..18944f4 100644
> --- a/drivers/net/gtp.c
> +++ b/drivers/net/gtp.c
> @@ -259,28 +259,30 @@ static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb,
>  	return iptunnel_pull_header(skb, hdrlen, skb->protocol, xnet);
>  }
>  
> -static void gtp_encap_disable(struct gtp_dev *gtp)
> -{
> -	if (gtp->sock0 && gtp->sock0->sk) {
> -		udp_sk(gtp->sock0->sk)->encap_type = 0;
> -		rcu_assign_sk_user_data(gtp->sock0->sk, NULL);
> -	}
> -	if (gtp->sock1u && gtp->sock1u->sk) {
> -		udp_sk(gtp->sock1u->sk)->encap_type = 0;
> -		rcu_assign_sk_user_data(gtp->sock1u->sk, NULL);
> -	}
> -
> -	gtp->sock0 = NULL;
> -	gtp->sock1u = NULL;
> -}
> -
>  static void gtp_encap_destroy(struct sock *sk)
>  {
>  	struct gtp_dev *gtp;
>  
>  	gtp = rcu_dereference_sk_user_data(sk);
> -	if (gtp)
> -		gtp_encap_disable(gtp);
> +	if (gtp) {
> +		udp_sk(sk)->encap_type = 0;
> +		rcu_assign_sk_user_data(sk, NULL);
> +	}
> +}
> +
> +static void gtp_encap_disable_sock(struct socket *sock)

Nitpick: Please, use sk for consistency:

        static void gtp_encap_disable_sock(struct socket *sk)

> +{
> +	if (!sock || !sock->sk)
> +		return;
> +
> +	gtp_encap_destroy(sock->sk);
> +	sockfd_put(sock);

This socket is created by userspace. If we hold it and the userspace
daemon stops without cleaning up configuration, we keep this socket
around that we cannot remove.

That's why we didn't hold any reference to this so far. I guess you
need this because of your follow up patch that catches this in the gtp
instance structure, that's why this slipped through.

> +}
> +
> +static void gtp_encap_disable(struct gtp_dev *gtp)
> +{
> +	gtp_encap_disable_sock(gtp->sock0);
> +	gtp_encap_disable_sock(gtp->sock1u);
>  }
>  
>  /* UDP encapsulation receive handler. See net/ipv4/udp.c.
> @@ -640,27 +642,24 @@ 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 net_device *dev, struct gtp_dev *gtp,
> -			    int fd_gtp0, int fd_gtp1);
> +static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[]);
> +static void gtp_encap_disable(struct gtp_dev *gtp);
>  
>  static int gtp_newlink(struct net *src_net, struct net_device *dev,
>  			struct nlattr *tb[], struct nlattr *data[])
>  {
> -	int hashsize, err, fd0, fd1;
> +	int hashsize, err;
>  	struct gtp_dev *gtp;
>  	struct gtp_net *gn;

Nitpick: We prefer declarations in this order:

  	struct gtp_dev *gtp;
  	struct gtp_net *gn;
	int hashsize, err;

>From longest line to shorter. I know we break this rule in many spots,
but it would be good if you keep this in mind.

> -	if (!data[IFLA_GTP_FD0] || !data[IFLA_GTP_FD1])
> +	if (!data[IFLA_GTP_FD0] && !data[IFLA_GTP_FD1])
>  		return -EINVAL;
>  
>  	gtp = netdev_priv(dev);
>  
> -	fd0 = nla_get_u32(data[IFLA_GTP_FD0]);
> -	fd1 = nla_get_u32(data[IFLA_GTP_FD1]);
> -
> -	err = gtp_encap_enable(dev, gtp, fd0, fd1);
> +	err = gtp_encap_enable(gtp, data);
>  	if (err < 0)
> -		goto out_err;
> +		return err;
>  
>  	if (!data[IFLA_GTP_PDP_HASHSIZE])
>  		hashsize = 1024;
> @@ -688,7 +687,6 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
>  	gtp_hashtable_free(gtp);
>  out_encap:
>  	gtp_encap_disable(gtp);
> -out_err:
>  	return err;
>  }
>  
> @@ -803,61 +801,73 @@ static void gtp_hashtable_free(struct gtp_dev *gtp)
>  	kfree(gtp->tid_hash);
>  }
>  
> -static int gtp_encap_enable(struct net_device *dev, struct gtp_dev *gtp,
> -			    int fd_gtp0, int fd_gtp1)
> +static struct socket *gtp_encap_enable_socket(int fd, int type,
> +					      struct gtp_dev *gtp)
>  {
>  	struct udp_tunnel_sock_cfg tuncfg = {NULL};
> -	struct socket *sock0, *sock1u;
> +	struct socket *sock;
>  	int err;
>  
> -	netdev_dbg(dev, "enable gtp on %d, %d\n", fd_gtp0, fd_gtp1);
> +	pr_debug("enable gtp on %d, %d\n", fd, type);
>  
> -	sock0 = sockfd_lookup(fd_gtp0, &err);
> -	if (sock0 == NULL) {
> -		netdev_dbg(dev, "socket fd=%d not found (gtp0)\n", fd_gtp0);
> -		return -ENOENT;
> +	sock = sockfd_lookup(fd, &err);
> +	if (!sock) {
> +		pr_debug("gtp socket fd=%d not found\n", fd);
> +		return NULL;
>  	}
>  
> -	if (sock0->sk->sk_protocol != IPPROTO_UDP) {
> -		netdev_dbg(dev, "socket fd=%d not UDP\n", fd_gtp0);
> +	if (sock->sk->sk_protocol != IPPROTO_UDP) {
> +		pr_debug("socket fd=%d not UDP\n", fd);

I would suggest you submit an initial patch to cover all this
conversion from netdev_dbg() to pr_debug() in first place, so we don't
do this here.

>  		err = -EINVAL;
> -		goto err1;
> +		goto out_sock;
>  	}
>  
> -	sock1u = sockfd_lookup(fd_gtp1, &err);
> -	if (sock1u == NULL) {
> -		netdev_dbg(dev, "socket fd=%d not found (gtp1u)\n", fd_gtp1);
> -		err = -ENOENT;
> -		goto err1;
> +	if (rcu_dereference_sk_user_data(sock->sk)) {
> +		err = -EBUSY;
> +		goto out_sock;
>  	}
>  
> -	if (sock1u->sk->sk_protocol != IPPROTO_UDP) {
> -		netdev_dbg(dev, "socket fd=%d not UDP\n", fd_gtp1);
> -		err = -EINVAL;
> -		goto err2;
> -	}
> -
> -	netdev_dbg(dev, "enable gtp on %p, %p\n", sock0, sock1u);
> -
> -	gtp->sock0 = sock0;
> -	gtp->sock1u = sock1u;
> -
>  	tuncfg.sk_user_data = gtp;
> +	tuncfg.encap_type = type;
>  	tuncfg.encap_rcv = gtp_encap_recv;
>  	tuncfg.encap_destroy = gtp_encap_destroy;
>  
> -	tuncfg.encap_type = UDP_ENCAP_GTP0;
> -	setup_udp_tunnel_sock(sock_net(gtp->sock0->sk), gtp->sock0, &tuncfg);
> -
> -	tuncfg.encap_type = UDP_ENCAP_GTP1U;
> -	setup_udp_tunnel_sock(sock_net(gtp->sock1u->sk), gtp->sock1u, &tuncfg);
> -
> -	err = 0;
> -err2:
> -	sockfd_put(sock1u);
> -err1:
> -	sockfd_put(sock0);
> -	return err;
> +	setup_udp_tunnel_sock(sock_net(sock->sk), sock, &tuncfg);
> +	return sock;
> +
> +out_sock:
> +	sockfd_put(sock);
> +	return ERR_PTR(err);
> +}
> +
> +static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[])
> +{
> +	struct socket *sock0 = NULL;
> +	struct socket *sock1u = NULL;

Same thing here regarding socket declaration.

> +	if (data[IFLA_GTP_FD0]) {
> +		u32 fd0 = nla_get_u32(data[IFLA_GTP_FD0]);
> +
> +		sock0 = gtp_encap_enable_socket(fd0, UDP_ENCAP_GTP0, gtp);
> +		if (IS_ERR(sock0))
> +			return PTR_ERR(sock0);
> +	}
> +
> +	if (data[IFLA_GTP_FD1]) {
> +		u32 fd1 = nla_get_u32(data[IFLA_GTP_FD1]);
> +
> +		sock1u = gtp_encap_enable_socket(fd1, UDP_ENCAP_GTP1U, gtp);
> +		if (IS_ERR(sock1u)) {
> +			if (sock0)
> +				sockfd_put(sock0);
> +			return PTR_ERR(sock1u);
> +		}
> +	}
> +
> +	gtp->sock0 = sock0;
> +	gtp->sock1u = sock1u;
> +
> +	return 0;
>  }
>  
>  static struct net_device *gtp_find_dev(struct net *net, int ifindex)
> -- 
> 2.10.2
> 

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 5/6] gtp: add socket to pdp context
  2017-02-02 13:56   ` Pablo Neira Ayuso
@ 2017-02-02 14:12     ` Andreas Schultz
  2017-02-02 14:28       ` Pablo Neira Ayuso
  0 siblings, 1 reply; 29+ messages in thread
From: Andreas Schultz @ 2017-02-02 14:12 UTC (permalink / raw)
  To: pablo; +Cc: netdev, laforge, Lionel Gauthier, openbsc

Hi,

----- On Feb 2, 2017, at 2:56 PM, pablo pablo@netfilter.org wrote:

> On Mon, Jan 30, 2017 at 05:37:12PM +0100, Andreas Schultz wrote:
>> Having the socket present in context simplifies the sending logic.
>> It also fixes the invalid assumption that we have to use the same
>> sending socket for all client IP's on a specific gtp interface.
>> 
>> Signed-off-by: Andreas Schultz <aschultz@tpip.net>
>> ---
>>  drivers/net/gtp.c | 72 ++++++++++++++++++++++++++++++-------------------------
>>  1 file changed, 39 insertions(+), 33 deletions(-)
>> 
>> diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
>> index 68c6c9b..ff00597 100644
>> --- a/drivers/net/gtp.c
>> +++ b/drivers/net/gtp.c
> [...]
>> @@ -984,16 +966,26 @@ static int ipv4_pdp_add(struct gtp_dev *gtp, struct
>> genl_info *info)
>>  	return 0;
>>  }
>>  
>> +static void pdp_context_free(struct rcu_head *head)
>> +{
>> +	struct pdp_ctx *pctx = container_of(head, struct pdp_ctx, rcu_head);
>> +
>> +	sock_put(pctx->sk);
>> +	kfree(pctx);
>> +}
>> +
>>  static void pdp_context_delete(struct pdp_ctx *pctx)
>>  {
>>  	hlist_del_rcu(&pctx->hlist_tid);
>>  	hlist_del_rcu(&pctx->hlist_addr);
>> -	kfree(pctx);
>> +	call_rcu(&pctx->rcu_head, pdp_context_free);
> 
> This is fixing incorrect rcu conversion in 4/6. Please, fix this there.

Ehm, right, but the kfree in 4/6 could have been a kfree_rcu instead without
the call_rcu.

Do you prefer to introduce the call_rcu in 4/6 and then just add the sock_put
in this patch or should I change 4/6 to kfree_rcu and do the call_rcu
conversion here?

Andreas

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 3/6] gtp: unify genl_find_pdp and prepare for per socket lookup
  2017-01-30 16:37 ` [PATCH net-next v2 3/6] gtp: unify genl_find_pdp and prepare for per socket lookup Andreas Schultz
@ 2017-02-02 14:19   ` Pablo Neira Ayuso
  2017-02-02 14:27     ` Andreas Schultz
  2017-02-06 13:56   ` Harald Welte
  1 sibling, 1 reply; 29+ messages in thread
From: Pablo Neira Ayuso @ 2017-02-02 14:19 UTC (permalink / raw)
  To: Andreas Schultz; +Cc: netdev, Harald Welte, Lionel Gauthier, openbsc

On Mon, Jan 30, 2017 at 05:37:10PM +0100, Andreas Schultz wrote:
> This unifies duplicate code into a helper. It also prepares the
> groundwork to add a lookup version that uses the socket to find
> attache pdp contexts.
> 
> Signed-off-by: Andreas Schultz <aschultz@tpip.net>
> ---
>  drivers/net/gtp.c | 120 +++++++++++++++++++++++-------------------------------
>  1 file changed, 51 insertions(+), 69 deletions(-)
> 
> diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
> index c96c71f..6b7a3c2 100644
> --- a/drivers/net/gtp.c
> +++ b/drivers/net/gtp.c
[...]
> +static struct pdp_ctx *gtp_genl_find_pdp(struct sk_buff *skb,
> +					 struct genl_info *info)
> +{
> +	struct pdp_ctx *pctx;
> +
> +	if (info->attrs[GTPA_LINK])
> +		pctx = gtp_genl_find_pdp_by_link(skb, info);
> +	else
> +		pctx = ERR_PTR(-EINVAL);
> +	if (!pctx)
> +		pctx = ERR_PTR(-ENOENT);
> +
> +	return pctx;
> +}

For gtp_genl_find_pdp(),  I think this is easier to read:

        if (!info->attrs[GTPA_LINK])
                return ERR_PTR(-EINVAL);

        pctx = gtp_genl_find_pdp_by_link(skb, info);
	if (!pctx)
		return ERR_PTR(-ENOENT);

        return pctx;

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 3/6] gtp: unify genl_find_pdp and prepare for per socket lookup
  2017-02-02 14:19   ` Pablo Neira Ayuso
@ 2017-02-02 14:27     ` Andreas Schultz
  2017-02-02 14:31       ` Pablo Neira Ayuso
  0 siblings, 1 reply; 29+ messages in thread
From: Andreas Schultz @ 2017-02-02 14:27 UTC (permalink / raw)
  To: pablo; +Cc: netdev, laforge, Lionel Gauthier, openbsc



----- On Feb 2, 2017, at 3:19 PM, pablo pablo@netfilter.org wrote:

> On Mon, Jan 30, 2017 at 05:37:10PM +0100, Andreas Schultz wrote:
>> This unifies duplicate code into a helper. It also prepares the
>> groundwork to add a lookup version that uses the socket to find
>> attache pdp contexts.
>> 
>> Signed-off-by: Andreas Schultz <aschultz@tpip.net>
>> ---
>>  drivers/net/gtp.c | 120 +++++++++++++++++++++++-------------------------------
>>  1 file changed, 51 insertions(+), 69 deletions(-)
>> 
>> diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
>> index c96c71f..6b7a3c2 100644
>> --- a/drivers/net/gtp.c
>> +++ b/drivers/net/gtp.c
> [...]
>> +static struct pdp_ctx *gtp_genl_find_pdp(struct sk_buff *skb,
>> +					 struct genl_info *info)
>> +{
>> +	struct pdp_ctx *pctx;
>> +
>> +	if (info->attrs[GTPA_LINK])
>> +		pctx = gtp_genl_find_pdp_by_link(skb, info);
>> +	else
>> +		pctx = ERR_PTR(-EINVAL);
>> +	if (!pctx)
>> +		pctx = ERR_PTR(-ENOENT);
>> +
>> +	return pctx;
>> +}
> 
> For gtp_genl_find_pdp(),  I think this is easier to read:
> 
>        if (!info->attrs[GTPA_LINK])
>                return ERR_PTR(-EINVAL);
> 
>        pctx = gtp_genl_find_pdp_by_link(skb, info);
>	if (!pctx)
>		return ERR_PTR(-ENOENT);
> 
>         return pctx;

Yes, but a later patch (will be submitted after this series is
accepted) will change that to:

        if (info->attrs[GTPA_LINK])
                pctx = gtp_genl_find_pdp_by_link(skb, info);
        else if (info->attrs[GTPA_FD])
                pctx = gtp_genl_find_pdp_by_socket(skb, info);
        else
                pctx = ERR_PTR(-EINVAL);

        if (!pctx)
                pctx = ERR_PTR(-ENOENT);

        return pctx;

I can use your form for this change, but have a larger change
later. Which way do you prefer it?

Andreas

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 5/6] gtp: add socket to pdp context
  2017-02-02 14:12     ` Andreas Schultz
@ 2017-02-02 14:28       ` Pablo Neira Ayuso
  2017-02-02 14:38         ` Andreas Schultz
  0 siblings, 1 reply; 29+ messages in thread
From: Pablo Neira Ayuso @ 2017-02-02 14:28 UTC (permalink / raw)
  To: Andreas Schultz; +Cc: netdev, laforge, Lionel Gauthier, openbsc

On Thu, Feb 02, 2017 at 03:12:55PM +0100, Andreas Schultz wrote:
> Hi,
> 
> ----- On Feb 2, 2017, at 2:56 PM, pablo pablo@netfilter.org wrote:
> 
> > On Mon, Jan 30, 2017 at 05:37:12PM +0100, Andreas Schultz wrote:
> >> Having the socket present in context simplifies the sending logic.
> >> It also fixes the invalid assumption that we have to use the same
> >> sending socket for all client IP's on a specific gtp interface.
> >> 
> >> Signed-off-by: Andreas Schultz <aschultz@tpip.net>
> >> ---
> >>  drivers/net/gtp.c | 72 ++++++++++++++++++++++++++++++-------------------------
> >>  1 file changed, 39 insertions(+), 33 deletions(-)
> >> 
> >> diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
> >> index 68c6c9b..ff00597 100644
> >> --- a/drivers/net/gtp.c
> >> +++ b/drivers/net/gtp.c
> > [...]
> >> @@ -984,16 +966,26 @@ static int ipv4_pdp_add(struct gtp_dev *gtp, struct
> >> genl_info *info)
> >>  	return 0;
> >>  }
> >>  
> >> +static void pdp_context_free(struct rcu_head *head)
> >> +{
> >> +	struct pdp_ctx *pctx = container_of(head, struct pdp_ctx, rcu_head);
> >> +
> >> +	sock_put(pctx->sk);
> >> +	kfree(pctx);
> >> +}
> >> +
> >>  static void pdp_context_delete(struct pdp_ctx *pctx)
> >>  {
> >>  	hlist_del_rcu(&pctx->hlist_tid);
> >>  	hlist_del_rcu(&pctx->hlist_addr);
> >> -	kfree(pctx);
> >> +	call_rcu(&pctx->rcu_head, pdp_context_free);
> > 
> > This is fixing incorrect rcu conversion in 4/6. Please, fix this there.
> 
> Ehm, right, but the kfree in 4/6 could have been a kfree_rcu instead without
> the call_rcu.
> 
> Do you prefer to introduce the call_rcu in 4/6 and then just add the sock_put
> in this patch or should I change 4/6 to kfree_rcu and do the call_rcu
> conversion here?

I suggest you just call kfree_rcu() from 4/6.

Regarding holding socket reference, see my comment for patch 1/6.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 1/6] gtp: make GTP sockets in gtp_newlink optional
  2017-02-02 14:10   ` Pablo Neira Ayuso
@ 2017-02-02 14:30     ` Andreas Schultz
  2017-02-02 14:32       ` Pablo Neira Ayuso
  0 siblings, 1 reply; 29+ messages in thread
From: Andreas Schultz @ 2017-02-02 14:30 UTC (permalink / raw)
  To: pablo; +Cc: netdev, laforge, Lionel Gauthier, openbsc



----- On Feb 2, 2017, at 3:10 PM, pablo pablo@netfilter.org wrote:

> On Mon, Jan 30, 2017 at 05:37:08PM +0100, Andreas Schultz wrote:
>> Having both GTPv0-U and GTPv1-U is not always desirable.
>> Fallback from GTPv1-U to GTPv0-U was depreciated from 3GPP
>> Rel-8 onwards. Post Rel-8 implementation are discuraged
>> from listening on the v0 port (see 3GPP TS 29.281, Sect. 1).
>> 
>> A future change will completely decouple the sockets from the
>> network device. Till then, at least one of the sockets needs to
>> be specified (either v0 or v1), the other is optional.
>> 
>> Signed-off-by: Andreas Schultz <aschultz@tpip.net>
>> ---
>>  drivers/net/gtp.c | 142 +++++++++++++++++++++++++++++-------------------------
>>  1 file changed, 76 insertions(+), 66 deletions(-)
>> 
>> diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
>> index bda0c64..18944f4 100644
>> --- a/drivers/net/gtp.c
>> +++ b/drivers/net/gtp.c
>> @@ -259,28 +259,30 @@ static int gtp1u_udp_encap_recv(struct gtp_dev *gtp,
>> struct sk_buff *skb,
>>  	return iptunnel_pull_header(skb, hdrlen, skb->protocol, xnet);
>>  }
>>  
>> -static void gtp_encap_disable(struct gtp_dev *gtp)
>> -{
>> -	if (gtp->sock0 && gtp->sock0->sk) {
>> -		udp_sk(gtp->sock0->sk)->encap_type = 0;
>> -		rcu_assign_sk_user_data(gtp->sock0->sk, NULL);
>> -	}
>> -	if (gtp->sock1u && gtp->sock1u->sk) {
>> -		udp_sk(gtp->sock1u->sk)->encap_type = 0;
>> -		rcu_assign_sk_user_data(gtp->sock1u->sk, NULL);
>> -	}
>> -
>> -	gtp->sock0 = NULL;
>> -	gtp->sock1u = NULL;
>> -}
>> -
>>  static void gtp_encap_destroy(struct sock *sk)
>>  {
>>  	struct gtp_dev *gtp;
>>  
>>  	gtp = rcu_dereference_sk_user_data(sk);
>> -	if (gtp)
>> -		gtp_encap_disable(gtp);
>> +	if (gtp) {
>> +		udp_sk(sk)->encap_type = 0;
>> +		rcu_assign_sk_user_data(sk, NULL);
>> +	}
>> +}
>> +
>> +static void gtp_encap_disable_sock(struct socket *sock)
> 
> Nitpick: Please, use sk for consistency:
> 
>        static void gtp_encap_disable_sock(struct socket *sk)
> 

Throughout the net subsystem 'struct socket` is always using sock
for variable names and 'struct sock' is using sk. I have been
following that convention, but can change to sk if you really want.

Andreas

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 3/6] gtp: unify genl_find_pdp and prepare for per socket lookup
  2017-02-02 14:27     ` Andreas Schultz
@ 2017-02-02 14:31       ` Pablo Neira Ayuso
  0 siblings, 0 replies; 29+ messages in thread
From: Pablo Neira Ayuso @ 2017-02-02 14:31 UTC (permalink / raw)
  To: Andreas Schultz; +Cc: netdev, laforge, Lionel Gauthier, openbsc

On Thu, Feb 02, 2017 at 03:27:17PM +0100, Andreas Schultz wrote:
> 
> 
> ----- On Feb 2, 2017, at 3:19 PM, pablo pablo@netfilter.org wrote:
> 
> > On Mon, Jan 30, 2017 at 05:37:10PM +0100, Andreas Schultz wrote:
> >> This unifies duplicate code into a helper. It also prepares the
> >> groundwork to add a lookup version that uses the socket to find
> >> attache pdp contexts.
> >> 
> >> Signed-off-by: Andreas Schultz <aschultz@tpip.net>
> >> ---
> >>  drivers/net/gtp.c | 120 +++++++++++++++++++++++-------------------------------
> >>  1 file changed, 51 insertions(+), 69 deletions(-)
> >> 
> >> diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
> >> index c96c71f..6b7a3c2 100644
> >> --- a/drivers/net/gtp.c
> >> +++ b/drivers/net/gtp.c
> > [...]
> >> +static struct pdp_ctx *gtp_genl_find_pdp(struct sk_buff *skb,
> >> +					 struct genl_info *info)
> >> +{
> >> +	struct pdp_ctx *pctx;
> >> +
> >> +	if (info->attrs[GTPA_LINK])
> >> +		pctx = gtp_genl_find_pdp_by_link(skb, info);
> >> +	else
> >> +		pctx = ERR_PTR(-EINVAL);
> >> +	if (!pctx)
> >> +		pctx = ERR_PTR(-ENOENT);
> >> +
> >> +	return pctx;
> >> +}
> > 
> > For gtp_genl_find_pdp(),  I think this is easier to read:
> > 
> >        if (!info->attrs[GTPA_LINK])
> >                return ERR_PTR(-EINVAL);
> > 
> >        pctx = gtp_genl_find_pdp_by_link(skb, info);
> >	if (!pctx)
> >		return ERR_PTR(-ENOENT);
> > 
> >         return pctx;
> 
> Yes, but a later patch (will be submitted after this series is
> accepted) will change that to:
> 
>         if (info->attrs[GTPA_LINK])
>                 pctx = gtp_genl_find_pdp_by_link(skb, info);
>         else if (info->attrs[GTPA_FD])
>                 pctx = gtp_genl_find_pdp_by_socket(skb, info);
>         else
>                 pctx = ERR_PTR(-EINVAL);
> 
>         if (!pctx)
>                 pctx = ERR_PTR(-ENOENT);
> 
>         return pctx;
> 
> I can use your form for this change, but have a larger change
> later. Which way do you prefer it?

I see, then leave this as it is.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 1/6] gtp: make GTP sockets in gtp_newlink optional
  2017-02-02 14:30     ` Andreas Schultz
@ 2017-02-02 14:32       ` Pablo Neira Ayuso
  0 siblings, 0 replies; 29+ messages in thread
From: Pablo Neira Ayuso @ 2017-02-02 14:32 UTC (permalink / raw)
  To: Andreas Schultz; +Cc: netdev, laforge, Lionel Gauthier, openbsc

On Thu, Feb 02, 2017 at 03:30:51PM +0100, Andreas Schultz wrote:
> 
> 
> ----- On Feb 2, 2017, at 3:10 PM, pablo pablo@netfilter.org wrote:
> 
> > On Mon, Jan 30, 2017 at 05:37:08PM +0100, Andreas Schultz wrote:
> >> Having both GTPv0-U and GTPv1-U is not always desirable.
> >> Fallback from GTPv1-U to GTPv0-U was depreciated from 3GPP
> >> Rel-8 onwards. Post Rel-8 implementation are discuraged
> >> from listening on the v0 port (see 3GPP TS 29.281, Sect. 1).
> >> 
> >> A future change will completely decouple the sockets from the
> >> network device. Till then, at least one of the sockets needs to
> >> be specified (either v0 or v1), the other is optional.
> >> 
> >> Signed-off-by: Andreas Schultz <aschultz@tpip.net>
> >> ---
> >>  drivers/net/gtp.c | 142 +++++++++++++++++++++++++++++-------------------------
> >>  1 file changed, 76 insertions(+), 66 deletions(-)
> >> 
> >> diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
> >> index bda0c64..18944f4 100644
> >> --- a/drivers/net/gtp.c
> >> +++ b/drivers/net/gtp.c
> >> @@ -259,28 +259,30 @@ static int gtp1u_udp_encap_recv(struct gtp_dev *gtp,
> >> struct sk_buff *skb,
> >>  	return iptunnel_pull_header(skb, hdrlen, skb->protocol, xnet);
> >>  }
> >>  
> >> -static void gtp_encap_disable(struct gtp_dev *gtp)
> >> -{
> >> -	if (gtp->sock0 && gtp->sock0->sk) {
> >> -		udp_sk(gtp->sock0->sk)->encap_type = 0;
> >> -		rcu_assign_sk_user_data(gtp->sock0->sk, NULL);
> >> -	}
> >> -	if (gtp->sock1u && gtp->sock1u->sk) {
> >> -		udp_sk(gtp->sock1u->sk)->encap_type = 0;
> >> -		rcu_assign_sk_user_data(gtp->sock1u->sk, NULL);
> >> -	}
> >> -
> >> -	gtp->sock0 = NULL;
> >> -	gtp->sock1u = NULL;
> >> -}
> >> -
> >>  static void gtp_encap_destroy(struct sock *sk)
> >>  {
> >>  	struct gtp_dev *gtp;
> >>  
> >>  	gtp = rcu_dereference_sk_user_data(sk);
> >> -	if (gtp)
> >> -		gtp_encap_disable(gtp);
> >> +	if (gtp) {
> >> +		udp_sk(sk)->encap_type = 0;
> >> +		rcu_assign_sk_user_data(sk, NULL);
> >> +	}
> >> +}
> >> +
> >> +static void gtp_encap_disable_sock(struct socket *sock)
> > 
> > Nitpick: Please, use sk for consistency:
> > 
> >        static void gtp_encap_disable_sock(struct socket *sk)
> > 
> 
> Throughout the net subsystem 'struct socket` is always using sock
> for variable names and 'struct sock' is using sk. I have been
> following that convention, but can change to sk if you really want.

Forget this, sorry. I think I read there 'struct sock'. I got confused
by patch context.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 5/6] gtp: add socket to pdp context
  2017-02-02 14:28       ` Pablo Neira Ayuso
@ 2017-02-02 14:38         ` Andreas Schultz
  2017-02-02 14:46           ` Pablo Neira Ayuso
  0 siblings, 1 reply; 29+ messages in thread
From: Andreas Schultz @ 2017-02-02 14:38 UTC (permalink / raw)
  To: pablo; +Cc: netdev, laforge, Lionel Gauthier, openbsc



----- On Feb 2, 2017, at 3:28 PM, pablo pablo@netfilter.org wrote:

> On Thu, Feb 02, 2017 at 03:12:55PM +0100, Andreas Schultz wrote:
>> Hi,
>> 
>> ----- On Feb 2, 2017, at 2:56 PM, pablo pablo@netfilter.org wrote:
>> 
>> > On Mon, Jan 30, 2017 at 05:37:12PM +0100, Andreas Schultz wrote:
>> >> Having the socket present in context simplifies the sending logic.
>> >> It also fixes the invalid assumption that we have to use the same
>> >> sending socket for all client IP's on a specific gtp interface.
>> >> 
>> >> Signed-off-by: Andreas Schultz <aschultz@tpip.net>
>> >> ---
>> >>  drivers/net/gtp.c | 72 ++++++++++++++++++++++++++++++-------------------------
>> >>  1 file changed, 39 insertions(+), 33 deletions(-)
>> >> 
>> >> diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
>> >> index 68c6c9b..ff00597 100644
>> >> --- a/drivers/net/gtp.c
>> >> +++ b/drivers/net/gtp.c
>> > [...]
>> >> @@ -984,16 +966,26 @@ static int ipv4_pdp_add(struct gtp_dev *gtp, struct
>> >> genl_info *info)
>> >>  	return 0;
>> >>  }
>> >>  
>> >> +static void pdp_context_free(struct rcu_head *head)
>> >> +{
>> >> +	struct pdp_ctx *pctx = container_of(head, struct pdp_ctx, rcu_head);
>> >> +
>> >> +	sock_put(pctx->sk);
>> >> +	kfree(pctx);
>> >> +}
>> >> +
>> >>  static void pdp_context_delete(struct pdp_ctx *pctx)
>> >>  {
>> >>  	hlist_del_rcu(&pctx->hlist_tid);
>> >>  	hlist_del_rcu(&pctx->hlist_addr);
>> >> -	kfree(pctx);
>> >> +	call_rcu(&pctx->rcu_head, pdp_context_free);
>> > 
>> > This is fixing incorrect rcu conversion in 4/6. Please, fix this there.
>> 
>> Ehm, right, but the kfree in 4/6 could have been a kfree_rcu instead without
>> the call_rcu.
>> 
>> Do you prefer to introduce the call_rcu in 4/6 and then just add the sock_put
>> in this patch or should I change 4/6 to kfree_rcu and do the call_rcu
>> conversion here?
> 
> I suggest you just call kfree_rcu() from 4/6.
> 
> Regarding holding socket reference, see my comment for patch 1/6.

This is going to be a problem at this stage of the changes.

The final goal is to have a reference from the socket to the pdp context.
Then, when the socket is closed, the pdp context can be destroyed.

However, at this point, only the netdevice knows about the contexts. So
when the socket is closed, the pdp context would have a dangling reference
to the socket.

I can integrate this change into the later one. But it will make that
change larger and more difficult to review.

I guess, I'm going to drop this change from this series and see if can
reorder the next part so that it still makes and I easy to review....

Andreas

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 5/6] gtp: add socket to pdp context
  2017-02-02 14:38         ` Andreas Schultz
@ 2017-02-02 14:46           ` Pablo Neira Ayuso
  2017-02-02 15:07             ` Andreas Schultz
  0 siblings, 1 reply; 29+ messages in thread
From: Pablo Neira Ayuso @ 2017-02-02 14:46 UTC (permalink / raw)
  To: Andreas Schultz; +Cc: netdev, laforge, Lionel Gauthier, openbsc

On Thu, Feb 02, 2017 at 03:38:07PM +0100, Andreas Schultz wrote:
> 
> 
> ----- On Feb 2, 2017, at 3:28 PM, pablo pablo@netfilter.org wrote:
> 
> > On Thu, Feb 02, 2017 at 03:12:55PM +0100, Andreas Schultz wrote:
> >> Hi,
> >> 
> >> ----- On Feb 2, 2017, at 2:56 PM, pablo pablo@netfilter.org wrote:
> >> 
> >> > On Mon, Jan 30, 2017 at 05:37:12PM +0100, Andreas Schultz wrote:
> >> >> Having the socket present in context simplifies the sending logic.
> >> >> It also fixes the invalid assumption that we have to use the same
> >> >> sending socket for all client IP's on a specific gtp interface.
> >> >> 
> >> >> Signed-off-by: Andreas Schultz <aschultz@tpip.net>
> >> >> ---
> >> >>  drivers/net/gtp.c | 72 ++++++++++++++++++++++++++++++-------------------------
> >> >>  1 file changed, 39 insertions(+), 33 deletions(-)
> >> >> 
> >> >> diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
> >> >> index 68c6c9b..ff00597 100644
> >> >> --- a/drivers/net/gtp.c
> >> >> +++ b/drivers/net/gtp.c
> >> > [...]
> >> >> @@ -984,16 +966,26 @@ static int ipv4_pdp_add(struct gtp_dev *gtp, struct
> >> >> genl_info *info)
> >> >>  	return 0;
> >> >>  }
> >> >>  
> >> >> +static void pdp_context_free(struct rcu_head *head)
> >> >> +{
> >> >> +	struct pdp_ctx *pctx = container_of(head, struct pdp_ctx, rcu_head);
> >> >> +
> >> >> +	sock_put(pctx->sk);
> >> >> +	kfree(pctx);
> >> >> +}
> >> >> +
> >> >>  static void pdp_context_delete(struct pdp_ctx *pctx)
> >> >>  {
> >> >>  	hlist_del_rcu(&pctx->hlist_tid);
> >> >>  	hlist_del_rcu(&pctx->hlist_addr);
> >> >> -	kfree(pctx);
> >> >> +	call_rcu(&pctx->rcu_head, pdp_context_free);
> >> > 
> >> > This is fixing incorrect rcu conversion in 4/6. Please, fix this there.
> >> 
> >> Ehm, right, but the kfree in 4/6 could have been a kfree_rcu instead without
> >> the call_rcu.
> >> 
> >> Do you prefer to introduce the call_rcu in 4/6 and then just add the sock_put
> >> in this patch or should I change 4/6 to kfree_rcu and do the call_rcu
> >> conversion here?
> > 
> > I suggest you just call kfree_rcu() from 4/6.
> > 
> > Regarding holding socket reference, see my comment for patch 1/6.
> 
> This is going to be a problem at this stage of the changes.
> 
> The final goal is to have a reference from the socket to the pdp context.

Is this just a cleanup? Or you need this sk caching for some follow up
work?

> Then, when the socket is closed, the pdp context can be destroyed.
>
> However, at this point, only the netdevice knows about the contexts. So
> when the socket is closed, the pdp context would have a dangling reference
> to the socket.
>
> I can integrate this change into the later one. But it will make that
> change larger and more difficult to review.
> 
> I guess, I'm going to drop this change from this series and see if can
> reorder the next part so that it still makes and I easy to review....

Agreed. Thanks.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 5/6] gtp: add socket to pdp context
  2017-02-02 14:46           ` Pablo Neira Ayuso
@ 2017-02-02 15:07             ` Andreas Schultz
  2017-02-06 14:04               ` Harald Welte
  0 siblings, 1 reply; 29+ messages in thread
From: Andreas Schultz @ 2017-02-02 15:07 UTC (permalink / raw)
  To: pablo; +Cc: netdev, laforge, Lionel Gauthier, openbsc



----- On Feb 2, 2017, at 3:46 PM, pablo pablo@netfilter.org wrote:

> On Thu, Feb 02, 2017 at 03:38:07PM +0100, Andreas Schultz wrote:
>> 
>> 
>> ----- On Feb 2, 2017, at 3:28 PM, pablo pablo@netfilter.org wrote:
>> 
>> > On Thu, Feb 02, 2017 at 03:12:55PM +0100, Andreas Schultz wrote:
>> >> Hi,
>> >> 
>> >> ----- On Feb 2, 2017, at 2:56 PM, pablo pablo@netfilter.org wrote:
>> >> 
>> >> > On Mon, Jan 30, 2017 at 05:37:12PM +0100, Andreas Schultz wrote:
>> >> >> Having the socket present in context simplifies the sending logic.
>> >> >> It also fixes the invalid assumption that we have to use the same
>> >> >> sending socket for all client IP's on a specific gtp interface.
>> >> >> 
>> >> >> Signed-off-by: Andreas Schultz <aschultz@tpip.net>
>> >> >> ---
>> >> >>  drivers/net/gtp.c | 72 ++++++++++++++++++++++++++++++-------------------------
>> >> >>  1 file changed, 39 insertions(+), 33 deletions(-)
>> >> >> 
>> >> >> diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
>> >> >> index 68c6c9b..ff00597 100644
>> >> >> --- a/drivers/net/gtp.c
>> >> >> +++ b/drivers/net/gtp.c
>> >> > [...]
>> >> >> @@ -984,16 +966,26 @@ static int ipv4_pdp_add(struct gtp_dev *gtp, struct
>> >> >> genl_info *info)
>> >> >>  	return 0;
>> >> >>  }
>> >> >>  
>> >> >> +static void pdp_context_free(struct rcu_head *head)
>> >> >> +{
>> >> >> +	struct pdp_ctx *pctx = container_of(head, struct pdp_ctx, rcu_head);
>> >> >> +
>> >> >> +	sock_put(pctx->sk);
>> >> >> +	kfree(pctx);
>> >> >> +}
>> >> >> +
>> >> >>  static void pdp_context_delete(struct pdp_ctx *pctx)
>> >> >>  {
>> >> >>  	hlist_del_rcu(&pctx->hlist_tid);
>> >> >>  	hlist_del_rcu(&pctx->hlist_addr);
>> >> >> -	kfree(pctx);
>> >> >> +	call_rcu(&pctx->rcu_head, pdp_context_free);
>> >> > 
>> >> > This is fixing incorrect rcu conversion in 4/6. Please, fix this there.
>> >> 
>> >> Ehm, right, but the kfree in 4/6 could have been a kfree_rcu instead without
>> >> the call_rcu.
>> >> 
>> >> Do you prefer to introduce the call_rcu in 4/6 and then just add the sock_put
>> >> in this patch or should I change 4/6 to kfree_rcu and do the call_rcu
>> >> conversion here?
>> > 
>> > I suggest you just call kfree_rcu() from 4/6.
>> > 
>> > Regarding holding socket reference, see my comment for patch 1/6.
>> 
>> This is going to be a problem at this stage of the changes.
>> 
>> The final goal is to have a reference from the socket to the pdp context.
> 
> Is this just a cleanup? Or you need this sk caching for some follow up
> work?

It's not caching, the plan is to completely remove the socket from the
GTP netdevice (as far as that is possible without breaking the existing API).

A GGSN or PGW can serve multiple APN's on the same GTP-U socket. Those APN's
can have overlapping IP address ranges. The only sensible way to handle
this, is to have a netdevice per APN. This breaks the current 1:1 relation
between sockets and netdevices.

Andreas

> 
>> Then, when the socket is closed, the pdp context can be destroyed.
>>
>> However, at this point, only the netdevice knows about the contexts. So
>> when the socket is closed, the pdp context would have a dangling reference
>> to the socket.
>>
>> I can integrate this change into the later one. But it will make that
>> change larger and more difficult to review.
>> 
>> I guess, I'm going to drop this change from this series and see if can
>> reorder the next part so that it still makes and I easy to review....
> 
> Agreed. Thanks.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 0/6] gtp: misc improvements
  2017-01-31 18:05 ` [PATCH net-next v2 0/6] gtp: misc improvements David Miller
@ 2017-02-06 13:46   ` Harald Welte
  0 siblings, 0 replies; 29+ messages in thread
From: Harald Welte @ 2017-02-06 13:46 UTC (permalink / raw)
  To: David Miller; +Cc: aschultz, pablo, netdev, Lionel.Gauthier, openbsc

Hi Dave and List,

On Tue, Jan 31, 2017 at 01:05:43PM -0500, David Miller wrote:
> Please someone with GTP knowledge properly review this series.

I am happy to provide review, but I was travelling and my time to work
on things outside my dayjob is typically quite limited.  So I'd like to
ask for a bit more patience for patch review from me.  Thanks for your
understanding.

Regards,
	Harald

-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 1/6] gtp: make GTP sockets in gtp_newlink optional
  2017-01-30 16:37 ` [PATCH net-next v2 1/6] gtp: make GTP sockets in gtp_newlink optional Andreas Schultz
  2017-02-02 14:10   ` Pablo Neira Ayuso
@ 2017-02-06 13:51   ` Harald Welte
  1 sibling, 0 replies; 29+ messages in thread
From: Harald Welte @ 2017-02-06 13:51 UTC (permalink / raw)
  To: Andreas Schultz; +Cc: Pablo Neira, netdev, Lionel Gauthier, openbsc

Hi Andreas,

my kernel coding skills are getting a bit rusty (no pun intended), and
I'll think others on this list are more capable to do so.  But let me at
least provide feedback from the "3GPP / GTP side":

On Mon, Jan 30, 2017 at 05:37:08PM +0100, Andreas Schultz wrote:
> Having both GTPv0-U and GTPv1-U is not always desirable.
> Fallback from GTPv1-U to GTPv0-U was depreciated from 3GPP
> Rel-8 onwards. Post Rel-8 implementation are discuraged
> from listening on the v0 port (see 3GPP TS 29.281, Sect. 1).

I confirm this and I think the related change should be applied.

> A future change will completely decouple the sockets from the
> network device. Till then, at least one of the sockets needs to
> be specified (either v0 or v1), the other is optional.

Makes sense.

-- 
- Harald Welte <laforge@netfilter.org>                 http://netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 2/6] gtp: merge gtp_get_net and gtp_genl_find_dev
  2017-01-30 16:37 ` [PATCH net-next v2 2/6] gtp: merge gtp_get_net and gtp_genl_find_dev Andreas Schultz
@ 2017-02-06 13:55   ` Harald Welte
  2017-02-13 14:13     ` Andreas Schultz
  0 siblings, 1 reply; 29+ messages in thread
From: Harald Welte @ 2017-02-06 13:55 UTC (permalink / raw)
  To: Andreas Schultz; +Cc: Pablo Neira, netdev, Lionel Gauthier, openbsc

Hi Andreas,

On Mon, Jan 30, 2017 at 05:37:09PM +0100, Andreas Schultz wrote:
> Both function are always used together with the final goal to
> get the gtp_dev. This simplifies the code by merging them together.

Ok, some code restructuring / unification, seems useful.

However:

> -			netdev_dbg(dev, "GTPv0-U: update tunnel id = %llx (pdp %p)\n",
> -				   pctx->u.v0.tid, pctx);
> +			pr_debug("GTPv0-U: update tunnel id = %llx (pdp %p)\n",
> +				 pctx->u.v0.tid, pctx);

(and other related changes) appear to be purely cosmetic and should thus
be unrelated to the function merging described in the change log
message.

-- 
- Harald Welte <laforge@netfilter.org>                 http://netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 3/6] gtp: unify genl_find_pdp and prepare for per socket lookup
  2017-01-30 16:37 ` [PATCH net-next v2 3/6] gtp: unify genl_find_pdp and prepare for per socket lookup Andreas Schultz
  2017-02-02 14:19   ` Pablo Neira Ayuso
@ 2017-02-06 13:56   ` Harald Welte
  1 sibling, 0 replies; 29+ messages in thread
From: Harald Welte @ 2017-02-06 13:56 UTC (permalink / raw)
  To: Andreas Schultz; +Cc: Pablo Neira, netdev, Lionel Gauthier, openbsc

On Mon, Jan 30, 2017 at 05:37:10PM +0100, Andreas Schultz wrote:
> Signed-off-by: Andreas Schultz <aschultz@tpip.net>

Acked-by: Harald Welte <laforge@gnumonks.org>

-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 4/6] gtp: consolidate pdp context destruction into helper
  2017-01-30 16:37 ` [PATCH net-next v2 4/6] gtp: consolidate pdp context destruction into helper Andreas Schultz
@ 2017-02-06 13:58   ` Harald Welte
  2017-02-13 14:14     ` Andreas Schultz
  0 siblings, 1 reply; 29+ messages in thread
From: Harald Welte @ 2017-02-06 13:58 UTC (permalink / raw)
  To: Andreas Schultz; +Cc: Pablo Neira, netdev, Lionel Gauthier, openbsc

Hi Andreas,

On Mon, Jan 30, 2017 at 05:37:11PM +0100, Andreas Schultz wrote:
> Consolidate duplicate code into helper.

Makes complete sense.

However:

> +static void pdp_context_delete(struct pdp_ctx *pctx);
> +

why introduce the forward-declaration and then define the function
further down in the file?  I think in general, it is preferred to put
helper functions on top, before their first use, so forward declarations
can be avoided?  Particularly if the helper function doesn't call any
other functions that are not yet declared at this point.

Please note the above might just be my personal taste, not sure if
that's a general habit in the kernel networking code these days.

So with or without the re-ordering:

Acked-by: Harald Welte <laforge@gnumonks.org>

-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 5/6] gtp: add socket to pdp context
  2017-02-02 15:07             ` Andreas Schultz
@ 2017-02-06 14:04               ` Harald Welte
  0 siblings, 0 replies; 29+ messages in thread
From: Harald Welte @ 2017-02-06 14:04 UTC (permalink / raw)
  To: Andreas Schultz; +Cc: pablo, netdev, Lionel Gauthier, openbsc

Dear All,

On Thu, Feb 02, 2017 at 04:07:23PM +0100, Andreas Schultz wrote:
> ----- On Feb 2, 2017, at 3:46 PM, pablo pablo@netfilter.org wrote:
> > On Thu, Feb 02, 2017 at 03:38:07PM +0100, Andreas Schultz wrote:
> >> ----- On Feb 2, 2017, at 3:28 PM, pablo pablo@netfilter.org wrote:
> >> > I suggest you just call kfree_rcu() from 4/6.
> >> > 
> >> > Regarding holding socket reference, see my comment for patch 1/6.
> >> 
> >> This is going to be a problem at this stage of the changes.
> >> 
> >> The final goal is to have a reference from the socket to the pdp context.
> > 
> > Is this just a cleanup? Or you need this sk caching for some follow up
> > work?
> 
> It's not caching, the plan is to completely remove the socket from the
> GTP netdevice (as far as that is possible without breaking the existing API).

I agree this is the way to go.  When I originally thought about the GTP
kernel tunneling module early on, I was not aware of the fact that
operators actually in practise run multiple "virtual GGSNs" on one IP
address/port.  From a pure technical point of view you would say "why
bother"?  They could just use separate IP addresses for each of them.
However, the reailty is that each new IP address that an operator uses
for a GGSN results in paper forms required to be exchanged between this
operator and all his roming partners, followed-up by manual
re-configuration of the policies on all of those roaming partners.  This
is time-consuming and error-prone, but hey, it's how the procedures
between GSMA members seem to work ;)

> A GGSN or PGW can serve multiple APN's on the same GTP-U socket. Those APN's
> can have overlapping IP address ranges. The only sensible way to handle
> this, is to have a netdevice per APN. This breaks the current 1:1 relation
> between sockets and netdevices.

Indeed.  So the question is how to do this best and how to keep
backwards compatibility of the netlink interface.  I don't claim to have
answers to that, sorry.

-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 2/6] gtp: merge gtp_get_net and gtp_genl_find_dev
  2017-02-06 13:55   ` Harald Welte
@ 2017-02-13 14:13     ` Andreas Schultz
  2017-02-13 14:51       ` Pablo Neira Ayuso
  0 siblings, 1 reply; 29+ messages in thread
From: Andreas Schultz @ 2017-02-13 14:13 UTC (permalink / raw)
  To: Harald Welte; +Cc: pablo, netdev, Lionel Gauthier, openbsc



----- On Feb 6, 2017, at 2:55 PM, Harald Welte laforge@netfilter.org wrote:

> Hi Andreas,
> 
> On Mon, Jan 30, 2017 at 05:37:09PM +0100, Andreas Schultz wrote:
>> Both function are always used together with the final goal to
>> get the gtp_dev. This simplifies the code by merging them together.
> 
> Ok, some code restructuring / unification, seems useful.
> 
> However:
> 
>> -			netdev_dbg(dev, "GTPv0-U: update tunnel id = %llx (pdp %p)\n",
>> -				   pctx->u.v0.tid, pctx);
>> +			pr_debug("GTPv0-U: update tunnel id = %llx (pdp %p)\n",
>> +				 pctx->u.v0.tid, pctx);
> 
> (and other related changes) appear to be purely cosmetic and should thus
> be unrelated to the function merging described in the change log
> message.

The dev argument has been removed from the surrounding function.
However, for those debug message having the network device information
is use full. I've modified the code in v3 a bit to keep the debug message.

Andreas

> 
> --
> - Harald Welte <laforge@netfilter.org>                 http://netfilter.org/
> ============================================================================
>  "Fragmentation is like classful addressing -- an interesting early
>   architectural error that shows how much experimentation was going
>    on while IP was being designed."                    -- Paul Vixie

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 4/6] gtp: consolidate pdp context destruction into helper
  2017-02-06 13:58   ` Harald Welte
@ 2017-02-13 14:14     ` Andreas Schultz
  0 siblings, 0 replies; 29+ messages in thread
From: Andreas Schultz @ 2017-02-13 14:14 UTC (permalink / raw)
  To: laforge; +Cc: pablo, netdev, Lionel Gauthier, openbsc



----- On Feb 6, 2017, at 2:58 PM, laforge laforge@gnumonks.org wrote:

> Hi Andreas,
> 
> On Mon, Jan 30, 2017 at 05:37:11PM +0100, Andreas Schultz wrote:
>> Consolidate duplicate code into helper.
> 
> Makes complete sense.
> 
> However:
> 
>> +static void pdp_context_delete(struct pdp_ctx *pctx);
>> +
> 
> why introduce the forward-declaration and then define the function
> further down in the file?  I think in general, it is preferred to put
> helper functions on top, before their first use, so forward declarations
> can be avoided?  Particularly if the helper function doesn't call any
> other functions that are not yet declared at this point.

I wanted to keep functions that work on the data structure close
together. I this case the function the initialized the pdp context
and the delete function for it.

Andreas

> 
> Please note the above might just be my personal taste, not sure if
> that's a general habit in the kernel networking code these days.
> 
> So with or without the re-ordering:
> 
> Acked-by: Harald Welte <laforge@gnumonks.org>
> 
> --
> - Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
> ============================================================================
> "Privacy in residential applications is a desirable marketing option."
>                                                   (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH net-next v2 2/6] gtp: merge gtp_get_net and gtp_genl_find_dev
  2017-02-13 14:13     ` Andreas Schultz
@ 2017-02-13 14:51       ` Pablo Neira Ayuso
  0 siblings, 0 replies; 29+ messages in thread
From: Pablo Neira Ayuso @ 2017-02-13 14:51 UTC (permalink / raw)
  To: Andreas Schultz; +Cc: Harald Welte, netdev, Lionel Gauthier, openbsc

On Mon, Feb 13, 2017 at 03:13:37PM +0100, Andreas Schultz wrote:
> 
> 
> ----- On Feb 6, 2017, at 2:55 PM, Harald Welte laforge@netfilter.org wrote:
> 
> > Hi Andreas,
> > 
> > On Mon, Jan 30, 2017 at 05:37:09PM +0100, Andreas Schultz wrote:
> >> Both function are always used together with the final goal to
> >> get the gtp_dev. This simplifies the code by merging them together.
> > 
> > Ok, some code restructuring / unification, seems useful.
> > 
> > However:
> > 
> >> -			netdev_dbg(dev, "GTPv0-U: update tunnel id = %llx (pdp %p)\n",
> >> -				   pctx->u.v0.tid, pctx);
> >> +			pr_debug("GTPv0-U: update tunnel id = %llx (pdp %p)\n",
> >> +				 pctx->u.v0.tid, pctx);
> > 
> > (and other related changes) appear to be purely cosmetic and should thus
> > be unrelated to the function merging described in the change log
> > message.
> 
> The dev argument has been removed from the surrounding function.
> However, for those debug message having the network device information
> is use full. I've modified the code in v3 a bit to keep the debug message.

There is no reason to replace netdev_dbg() by pr_debug(). With several
gtp devices in place, this debugging will render completely useless
since you cannot know what device has triggered the debugging mesage.

A better solution would be to simply remove this debugging thing. This
actually is only useful at early development stage IMO.

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2017-02-13 14:51 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-30 16:37 [PATCH net-next v2 0/6] gtp: misc improvements Andreas Schultz
2017-01-30 16:37 ` [PATCH net-next v2 1/6] gtp: make GTP sockets in gtp_newlink optional Andreas Schultz
2017-02-02 14:10   ` Pablo Neira Ayuso
2017-02-02 14:30     ` Andreas Schultz
2017-02-02 14:32       ` Pablo Neira Ayuso
2017-02-06 13:51   ` Harald Welte
2017-01-30 16:37 ` [PATCH net-next v2 2/6] gtp: merge gtp_get_net and gtp_genl_find_dev Andreas Schultz
2017-02-06 13:55   ` Harald Welte
2017-02-13 14:13     ` Andreas Schultz
2017-02-13 14:51       ` Pablo Neira Ayuso
2017-01-30 16:37 ` [PATCH net-next v2 3/6] gtp: unify genl_find_pdp and prepare for per socket lookup Andreas Schultz
2017-02-02 14:19   ` Pablo Neira Ayuso
2017-02-02 14:27     ` Andreas Schultz
2017-02-02 14:31       ` Pablo Neira Ayuso
2017-02-06 13:56   ` Harald Welte
2017-01-30 16:37 ` [PATCH net-next v2 4/6] gtp: consolidate pdp context destruction into helper Andreas Schultz
2017-02-06 13:58   ` Harald Welte
2017-02-13 14:14     ` Andreas Schultz
2017-01-30 16:37 ` [PATCH net-next v2 5/6] gtp: add socket to pdp context Andreas Schultz
2017-02-02 13:56   ` Pablo Neira Ayuso
2017-02-02 14:12     ` Andreas Schultz
2017-02-02 14:28       ` Pablo Neira Ayuso
2017-02-02 14:38         ` Andreas Schultz
2017-02-02 14:46           ` Pablo Neira Ayuso
2017-02-02 15:07             ` Andreas Schultz
2017-02-06 14:04               ` Harald Welte
2017-01-30 16:37 ` [PATCH net-next v2 6/6] gtp: consolidate gtp socket rx path Andreas Schultz
2017-01-31 18:05 ` [PATCH net-next v2 0/6] gtp: misc improvements David Miller
2017-02-06 13:46   ` Harald Welte

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.