[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20201211122612.869225-13-jonas@norrbonn.se>
Date: Fri, 11 Dec 2020 13:26:12 +0100
From: Jonas Bonn <jonas@...rbonn.se>
To: netdev@...r.kernel.org
Cc: pablo@...filter.org, laforge@...monks.org,
Jonas Bonn <jonas@...rbonn.se>
Subject: [PATCH net-next v2 12/12] gtp: add dst_cache to tunnels
Destination caching on a per-tunnel basis is a performance win, so we
enable this unconditionally for the module.
Signed-off-by: Jonas Bonn <jonas@...rbonn.se>
---
drivers/net/Kconfig | 1 +
drivers/net/gtp.c | 27 +++++++++++++++++++++++++++
2 files changed, 28 insertions(+)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 260f9f46668b..f79277222125 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -276,6 +276,7 @@ config GTP
tristate "GPRS Tunneling Protocol datapath (GTP-U)"
depends on INET
select NET_UDP_TUNNEL
+ select DST_CACHE
help
This allows one to create gtp virtual interfaces that provide
the GPRS Tunneling Protocol datapath (GTP-U). This tunneling protocol
diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 40bbbe8cfad6..6708738681d2 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -64,6 +64,8 @@ struct pdp_ctx {
struct sock *sk;
struct net_device *dev;
+ struct dst_cache dst_cache;
+
atomic_t tx_seq;
struct rcu_head rcu_head;
};
@@ -577,9 +579,15 @@ static struct rtable *gtp_get_v4_rt(struct sk_buff *skb,
__be32 *saddr)
{
const struct sock *sk = pctx->sk;
+ struct dst_cache *dst_cache;
struct rtable *rt = NULL;
struct flowi4 fl4;
+ dst_cache = (struct dst_cache *)&pctx->dst_cache;
+ rt = dst_cache_get_ip4(dst_cache, saddr);
+ if (rt)
+ return rt;
+
memset(&fl4, 0, sizeof(fl4));
fl4.flowi4_oif = sk->sk_bound_dev_if;
fl4.daddr = ipv4(&pctx->peer_addr);
@@ -600,6 +608,8 @@ static struct rtable *gtp_get_v4_rt(struct sk_buff *skb,
*saddr = fl4.saddr;
+ dst_cache_set_ip4(dst_cache, &rt->dst, *saddr);
+
return rt;
}
@@ -610,8 +620,14 @@ static struct dst_entry *gtp_get_v6_dst(struct sk_buff *skb,
{
const struct sock *sk = pctx->sk;
struct dst_entry *dst = NULL;
+ struct dst_cache *dst_cache;
struct flowi6 fl6;
+ dst_cache = (struct dst_cache *)&pctx->dst_cache;
+ dst = dst_cache_get_ip6(dst_cache, saddr);
+ if (dst)
+ return dst;
+
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_mark = skb->mark;
fl6.flowi6_proto = IPPROTO_UDP;
@@ -630,6 +646,8 @@ static struct dst_entry *gtp_get_v6_dst(struct sk_buff *skb,
*saddr = fl6.saddr;
+ dst_cache_set_ip6(dst_cache, dst, saddr);
+
return dst;
}
@@ -1236,6 +1254,8 @@ static void pdp_fill(struct pdp_ctx *pctx, struct genl_info *info)
pctx->gtp_version = nla_get_u32(info->attrs[GTPA_VERSION]);
pctx->flags = 0;
+ dst_cache_reset(&pctx->dst_cache);
+
if (info->attrs[GTPA_PEER_IPV6]) {
pctx->flags |= PDP_F_PEER_V6;
pctx->peer_addr = nla_get_in6_addr(info->attrs[GTPA_PEER_IPV6]);
@@ -1331,6 +1351,11 @@ static struct pdp_ctx *gtp_pdp_add(struct gtp_dev *gtp, struct sock *sk,
if (pctx == NULL)
return ERR_PTR(-ENOMEM);
+ if (dst_cache_init(&pctx->dst_cache, GFP_ATOMIC)) {
+ kfree(pctx);
+ return ERR_PTR(-ENOBUFS);
+ }
+
sock_hold(sk);
pctx->sk = sk;
pctx->dev = gtp->dev;
@@ -1374,6 +1399,8 @@ static void pdp_context_free(struct rcu_head *head)
{
struct pdp_ctx *pctx = container_of(head, struct pdp_ctx, rcu_head);
+ dst_cache_destroy(&pctx->dst_cache);
+
sock_put(pctx->sk);
kfree(pctx);
}
--
2.27.0
Powered by blists - more mailing lists