lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20201211122612.869225-12-jonas@norrbonn.se>
Date:   Fri, 11 Dec 2020 13:26:11 +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 11/12] gtp: netlink update for ipv6

This patch adds the netlink changes required to support IPv6.

Signed-off-by: Jonas Bonn <jonas@...rbonn.se>
---
 drivers/net/gtp.c        | 84 ++++++++++++++++++++++++++++++----------
 include/uapi/linux/gtp.h |  2 +
 2 files changed, 65 insertions(+), 21 deletions(-)

diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 4c902bffefa3..40bbbe8cfad6 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -1231,11 +1231,26 @@ static struct gtp_dev *gtp_find_dev(struct net *src_net, struct nlattr *nla[])
 	return gtp;
 }
 
-static void ipv4_pdp_fill(struct pdp_ctx *pctx, struct genl_info *info)
+static void pdp_fill(struct pdp_ctx *pctx, struct genl_info *info)
 {
 	pctx->gtp_version = nla_get_u32(info->attrs[GTPA_VERSION]);
-	ipv4(&pctx->peer_addr) = nla_get_be32(info->attrs[GTPA_PEER_ADDRESS]);
-	ipv4(&pctx->ms_addr) = nla_get_be32(info->attrs[GTPA_MS_ADDRESS]);
+	pctx->flags = 0;
+
+	if (info->attrs[GTPA_PEER_IPV6]) {
+		pctx->flags |= PDP_F_PEER_V6;
+		pctx->peer_addr = nla_get_in6_addr(info->attrs[GTPA_PEER_IPV6]);
+	} else
+		ipv6_addr_set_v4mapped(
+				nla_get_be32(info->attrs[GTPA_PEER_ADDRESS]),
+				&pctx->peer_addr);
+
+	if (info->attrs[GTPA_MS_IPV6]) {
+		pctx->flags |= PDP_F_MS_V6;
+		pctx->ms_addr = nla_get_in6_addr(info->attrs[GTPA_MS_IPV6]);
+	} else
+		ipv6_addr_set_v4mapped(
+				nla_get_be32(info->attrs[GTPA_MS_ADDRESS]),
+				&pctx->ms_addr);
 
 	switch (pctx->gtp_version) {
 	case GTP_V0:
@@ -1263,13 +1278,20 @@ static struct pdp_ctx *gtp_pdp_add(struct gtp_dev *gtp, struct sock *sk,
 	u32 hash_ms, hash_tid = 0;
 	unsigned int version;
 	bool found = false;
-	__be32 ms_addr;
 
-	ms_addr = nla_get_be32(info->attrs[GTPA_MS_ADDRESS]);
-	hash_ms = ipv4_hashfn(ms_addr) % gtp->hash_size;
+	if (info->attrs[GTPA_MS_IPV6]) {
+		struct in6_addr ms_addr_v6;
+		ms_addr_v6 = nla_get_in6_addr(info->attrs[GTPA_MS_IPV6]);
+		hash_ms = ipv6_hashfn(&ms_addr_v6) % gtp->hash_size;
+		pctx = ipv6_pdp_find(gtp, &ms_addr_v6);
+	} else {
+		__be32 ms_addr;
+		ms_addr = nla_get_be32(info->attrs[GTPA_MS_ADDRESS]);
+		hash_ms = ipv4_hashfn(ms_addr) % gtp->hash_size;
+		pctx = ipv4_pdp_find(gtp, ms_addr);
+	}
 	version = nla_get_u32(info->attrs[GTPA_VERSION]);
 
-	pctx = ipv4_pdp_find(gtp, ms_addr);
 	if (pctx)
 		found = true;
 	if (version == GTP_V0)
@@ -1292,7 +1314,7 @@ static struct pdp_ctx *gtp_pdp_add(struct gtp_dev *gtp, struct sock *sk,
 		if (!pctx)
 			pctx = pctx_tid;
 
-		ipv4_pdp_fill(pctx, info);
+		pdp_fill(pctx, info);
 
 		if (pctx->gtp_version == GTP_V0)
 			netdev_dbg(dev, "GTPv0-U: update tunnel id = %llx (pdp %p)\n",
@@ -1312,7 +1334,7 @@ static struct pdp_ctx *gtp_pdp_add(struct gtp_dev *gtp, struct sock *sk,
 	sock_hold(sk);
 	pctx->sk = sk;
 	pctx->dev = gtp->dev;
-	ipv4_pdp_fill(pctx, info);
+	pdp_fill(pctx, info);
 	atomic_set(&pctx->tx_seq, 0);
 
 	switch (pctx->gtp_version) {
@@ -1334,14 +1356,14 @@ static struct pdp_ctx *gtp_pdp_add(struct gtp_dev *gtp, struct sock *sk,
 
 	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, &ipv4(&pctx->peer_addr),
-			   &ipv4(&pctx->ms_addr), pctx);
+		netdev_dbg(dev, "GTPv0-U: new PDP ctx id=%llx ssgn=%pI6 ms=%pI6 (pdp=%p)\n",
+			   pctx->u.v0.tid, &pctx->peer_addr,
+			   &pctx->ms_addr, pctx);
 		break;
 	case GTP_V1:
-		netdev_dbg(dev, "GTPv1-U: new PDP ctx id=%x/%x ssgn=%pI4 ms=%pI4 (pdp=%p)\n",
+		netdev_dbg(dev, "GTPv1-U: new PDP ctx id=%x/%x ssgn=%pI6 ms=%pI6 (pdp=%p)\n",
 			   pctx->u.v1.i_tei, pctx->u.v1.o_tei,
-			   &ipv4(&pctx->peer_addr), &ipv4(&pctx->ms_addr), pctx);
+			   &pctx->peer_addr, &pctx->ms_addr, pctx);
 		break;
 	}
 
@@ -1374,9 +1396,13 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info)
 	int err;
 
 	if (!info->attrs[GTPA_VERSION] ||
-	    !info->attrs[GTPA_LINK] ||
-	    !info->attrs[GTPA_PEER_ADDRESS] ||
-	    !info->attrs[GTPA_MS_ADDRESS])
+	    !info->attrs[GTPA_LINK])
+		return -EINVAL;
+
+	if (!info->attrs[GTPA_PEER_ADDRESS] == !info->attrs[GTPA_PEER_IPV6])
+		return -EINVAL;
+
+	if (!info->attrs[GTPA_MS_ADDRESS] == !info->attrs[GTPA_MS_IPV6])
 		return -EINVAL;
 
 	version = nla_get_u32(info->attrs[GTPA_VERSION]);
@@ -1439,7 +1465,11 @@ static struct pdp_ctx *gtp_find_pdp_by_link(struct net *net,
 	if (!gtp)
 		return ERR_PTR(-ENODEV);
 
-	if (nla[GTPA_MS_ADDRESS]) {
+	if (nla[GTPA_MS_IPV6]) {
+		struct in6_addr ip = nla_get_in6_addr(nla[GTPA_MS_IPV6]);
+
+		return ipv6_pdp_find(gtp, &ip);
+	} else if (nla[GTPA_MS_ADDRESS]) {
 		__be32 ip = nla_get_be32(nla[GTPA_MS_ADDRESS]);
 
 		return ipv4_pdp_find(gtp, ip);
@@ -1522,9 +1552,19 @@ static int gtp_genl_fill_info(struct sk_buff *skb, u32 snd_portid, u32 snd_seq,
 		goto nlmsg_failure;
 
 	if (nla_put_u32(skb, GTPA_VERSION, pctx->gtp_version) ||
-	    nla_put_u32(skb, GTPA_LINK, pctx->dev->ifindex) ||
-	    nla_put_be32(skb, GTPA_PEER_ADDRESS, ipv4(&pctx->peer_addr)) ||
-	    nla_put_be32(skb, GTPA_MS_ADDRESS, ipv4(&pctx->ms_addr)))
+	    nla_put_u32(skb, GTPA_LINK, pctx->dev->ifindex))
+		goto nla_put_failure;
+
+	if ((pctx->flags & PDP_F_PEER_V6) &&
+	   nla_put_in6_addr(skb, GTPA_PEER_IPV6, &pctx->peer_addr))
+		goto nla_put_failure;
+	else if (nla_put_be32(skb, GTPA_PEER_ADDRESS, ipv4(&pctx->peer_addr)))
+		goto nla_put_failure;
+
+	if ((pctx->flags & PDP_F_MS_V6) &&
+	    nla_put_in6_addr(skb, GTPA_MS_IPV6, &pctx->ms_addr))
+		goto nla_put_failure;
+	else if (nla_put_be32(skb, GTPA_MS_ADDRESS, ipv4(&pctx->ms_addr)))
 		goto nla_put_failure;
 
 	switch (pctx->gtp_version) {
@@ -1660,6 +1700,8 @@ static const struct nla_policy gtp_genl_policy[GTPA_MAX + 1] = {
 	[GTPA_TID]		= { .type = NLA_U64, },
 	[GTPA_PEER_ADDRESS]	= { .type = NLA_U32, },
 	[GTPA_MS_ADDRESS]	= { .type = NLA_U32, },
+	[GTPA_PEER_IPV6]	= { .len = sizeof(struct in6_addr), },
+	[GTPA_MS_IPV6]		= { .len = sizeof(struct in6_addr), },
 	[GTPA_FLOW]		= { .type = NLA_U16, },
 	[GTPA_NET_NS_FD]	= { .type = NLA_U32, },
 	[GTPA_I_TEI]		= { .type = NLA_U32, },
diff --git a/include/uapi/linux/gtp.h b/include/uapi/linux/gtp.h
index 79f9191bbb24..5fe0ca6a917e 100644
--- a/include/uapi/linux/gtp.h
+++ b/include/uapi/linux/gtp.h
@@ -30,6 +30,8 @@ enum gtp_attrs {
 	GTPA_I_TEI,	/* for GTPv1 only */
 	GTPA_O_TEI,	/* for GTPv1 only */
 	GTPA_PAD,
+	GTPA_PEER_IPV6,
+	GTPA_MS_IPV6,
 	__GTPA_MAX,
 };
 #define GTPA_MAX (__GTPA_MAX + 1)
-- 
2.27.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ