From: Andreas Schultz <aschultz@tpip.net>
To: Pablo Neira <pablo@netfilter.org>
Cc: netdev@vger.kernel.org, Harald Welte <laforge@gnumonks.org>,
Lionel Gauthier <Lionel.Gauthier@eurecom.fr>,
openbsc@lists.osmocom.org
Subject: [PATCH 5/6] gtp: add socket to pdp context
Date: Mon, 30 Jan 2017 17:31:59 +0100 [thread overview]
Message-ID: <20170130163200.17070-6-aschultz@tpip.net> (raw)
In-Reply-To: <20170130163200.17070-1-aschultz@tpip.net>
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
next prev parent reply other threads:[~2017-01-30 16:34 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-30 16:31 [PATCH 0/6] gtp: misc improvements Andreas Schultz
2017-01-30 16:31 ` [PATCH 1/6] gtp: make GTP sockets in gtp_newlink optional Andreas Schultz
2017-01-30 16:31 ` [PATCH 2/6] gtp: merge gtp_get_net and gtp_genl_find_dev Andreas Schultz
2017-01-30 16:31 ` [PATCH 3/6] gtp: unify genl_find_pdp and prepare for per socket lookup Andreas Schultz
2017-01-30 16:31 ` [PATCH 4/6] gtp: consolidate pdp context destruction into helper Andreas Schultz
2017-01-30 16:31 ` Andreas Schultz [this message]
2017-01-30 16:32 ` [PATCH 6/6] gtp: consolidate gtp socket rx path Andreas Schultz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170130163200.17070-6-aschultz@tpip.net \
--to=aschultz@tpip.net \
--cc=Lionel.Gauthier@eurecom.fr \
--cc=laforge@gnumonks.org \
--cc=netdev@vger.kernel.org \
--cc=openbsc@lists.osmocom.org \
--cc=pablo@netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).