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-next>] [day] [month] [year] [list]
Message-ID: <71eb2d7b-6afa-48fd-af96-140dd6ddd1e0.mao-linux@maojianwei.com>
Date:   Sun, 19 Apr 2020 11:33:44 +0800
From:   "Jianwei Mao (Mao)" <mao-linux@...jianwei.com>
To:     "netdev" <netdev@...r.kernel.org>
Cc:     "davem" <davem@...emloft.net>, "kuznet" <kuznet@....inr.ac.ru>,
        "yoshfuji" <yoshfuji@...ux-ipv6.org>, "kuba" <kuba@...nel.org>,
        "maojianwei" <maojianwei@...wei.com>
Subject: [PATCH net-next] net: ipv6: support Application-aware IPv6 Network (APN6)

Hi friends,

I would like to propose this new feature for you and linux networking:
support Application-aware IPv6 Network (APN6)
Content of my patch file is as follow. Appreciate your reviews and comments, thanks :)


Feature: support Application-aware IPv6 Network (APN6)

This feature allows application client/server set APN6 infos to sockets
they are using to communicate to each other, by setsockopt().

APN6 infos include three fields now: SLA, AppID and UserID. This APN6
infos will be encapsulated in IPv6 Hop-by-Hop(HBH) extension header,
as an APN6 option TLV.

After that, network can provide specific performance for Apps, such as,
low-latency for online Games, low-jitter for industrial control,
enough-bandwidth for video conference/remote medical system, etc.

This feature is to support APN6 IETF Standard draft:
https://datatracker.ietf.org/doc/draft-li-6man-app-aware-ipv6-network

We made two changes:
1. add IPV6_APN6 as an 'optname' for IPPROTO_IPV6 'level'.
2. add a function to generate IPv6 APN6 HBH header, and re-use
    IPV6_HOPOPTS procedure to set this header to socket opt.

Signed-off-by: Jianwei Mao <mao-linux@...jianwei.com>
---
 include/uapi/linux/in6.h |  4 ++
 net/ipv6/ipv6_sockglue.c | 97 +++++++++++++++++++++++++++++++++-------
 2 files changed, 86 insertions(+), 15 deletions(-)

diff --git a/include/uapi/linux/in6.h b/include/uapi/linux/in6.h
index 9f2273a08356..6601cad58415 100644
--- a/include/uapi/linux/in6.h
+++ b/include/uapi/linux/in6.h
@@ -297,4 +297,8 @@ struct in6_flowlabel_req {
  * ...
  * MRT6_MAX
  */
+
+/* APN6: Application-aware IPv6 Network */
+#define IPV6_APN6		81
+
 #endif /* _UAPI_LINUX_IN6_H */
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index debdaeba5d8c..929cbaf27c27 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -136,6 +136,59 @@ static bool setsockopt_needs_rtnl(int optname)
 	return false;
 }
 
+#define APN6_HBH_LEN 16
+#define APN6_HBH_HDR_LEN 4
+#define APN6_OPTION_TYPE 0x03
+#define APN6_OPTION_LEN (APN6_HBH_LEN - APN6_HBH_HDR_LEN)
+#define APN6_SLA_SIZE 4
+#define APN6_APPID_SIZE 4
+#define APN6_USERID_SIZE 4
+/* Return APN6 Hop-by-Hop(HBH) extension header */
+static void *generate_apn6_hopopts(char __user *optval, unsigned int optlen)
+{
+	unsigned char *hbh;
+	unsigned int sla, app_id, user_id;
+
+	if (optlen < (sizeof(unsigned int) * 3))
+		return NULL;
+	else if (!optval)
+		return NULL;
+
+	if (get_user(sla, ((unsigned int __user *)optval)) ||
+	    get_user(app_id, ((unsigned int __user *)optval) + 1) ||
+	    get_user(user_id, ((unsigned int __user *)optval) + 2))
+		return ERR_PTR(-EFAULT);
+
+	pr_info("APN6: Get info: SLA:%08X AppID:%08X UserID:%08X",
+		    sla, app_id, user_id);
+
+	hbh = kzalloc(APN6_HBH_LEN, GFP_KERNEL);
+	// hbh[0] is 0x0 now, and will be set natively when sending packets.
+	hbh[1] = (APN6_HBH_LEN >> 3) - 1;
+	hbh[2] = APN6_OPTION_TYPE;
+	hbh[3] = APN6_OPTION_LEN;
+
+	sla = htonl(sla);
+	app_id = htonl(app_id);
+	user_id = htonl(user_id);
+	memcpy(hbh + APN6_HBH_HDR_LEN, &sla, APN6_SLA_SIZE);
+	memcpy(hbh + APN6_HBH_HDR_LEN + APN6_SLA_SIZE, &app_id, APN6_APPID_SIZE);
+	memcpy(hbh + APN6_HBH_HDR_LEN + APN6_SLA_SIZE + APN6_APPID_SIZE,
+	       &user_id, APN6_USERID_SIZE);
+
+	pr_info("APN6: Generate APN6 Hop-by-Hop extension header:\n"
+			"%02X %02X %02X %02X\n"
+			"%02X %02X %02X %02X\n"
+			"%02X %02X %02X %02X\n"
+			"%02X %02X %02X %02X",
+			hbh[0], hbh[1], hbh[2], hbh[3],
+			hbh[4], hbh[5], hbh[6], hbh[7],
+			hbh[8], hbh[9], hbh[10], hbh[11],
+			hbh[12], hbh[13], hbh[14], hbh[15]);
+
+	return hbh;
+}
+
 static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
 		    char __user *optval, unsigned int optlen)
 {
@@ -400,34 +453,48 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
 	case IPV6_RTHDRDSTOPTS:
 	case IPV6_RTHDR:
 	case IPV6_DSTOPTS:
+	case IPV6_APN6:
 	{
 		struct ipv6_txoptions *opt;
 		struct ipv6_opt_hdr *new = NULL;
 
 		/* hop-by-hop / destination options are privileged option */
 		retv = -EPERM;
-		if (optname != IPV6_RTHDR && !ns_capable(net->user_ns, CAP_NET_RAW))
+		if (optname != IPV6_APN6 && optname != IPV6_RTHDR &&
+		    !ns_capable(net->user_ns, CAP_NET_RAW))
 			break;
 
-		/* remove any sticky options header with a zero option
-		 * length, per RFC3542.
-		 */
-		if (optlen == 0)
-			optval = NULL;
-		else if (!optval)
-			goto e_inval;
-		else if (optlen < sizeof(struct ipv6_opt_hdr) ||
-			 optlen & 0x7 || optlen > 8 * 255)
-			goto e_inval;
-		else {
-			new = memdup_user(optval, optlen);
+		if (optname == IPV6_APN6) {
+			new = generate_apn6_hopopts(optval, optlen);
 			if (IS_ERR(new)) {
 				retv = PTR_ERR(new);
+				pr_warn("APN6: Fail when generate HBH, %d", retv);
 				break;
 			}
-			if (unlikely(ipv6_optlen(new) > optlen)) {
-				kfree(new);
+			// next steps are same as IPV6_HOPOPTS procedure,
+			// so we can reuse it.
+			optname = IPV6_HOPOPTS;
+		} else {
+			/* remove any sticky options header with a zero option
+			 * length, per RFC3542.
+			 */
+			if (optlen == 0)
+				optval = NULL;
+			else if (!optval)
+				goto e_inval;
+			else if (optlen < sizeof(struct ipv6_opt_hdr) ||
+				     optlen & 0x7 || optlen > 8 * 255)
 				goto e_inval;
+			else {
+				new = memdup_user(optval, optlen);
+				if (IS_ERR(new)) {
+					retv = PTR_ERR(new);
+					break;
+				}
+				if (unlikely(ipv6_optlen(new) > optlen)) {
+					kfree(new);
+					goto e_inval;
+				}
 			}
 		}
 
-- 
2.17.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ