netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next] net: ipv6: support Application-aware IPv6 Network (APN6)
@ 2020-04-19  3:33 Jianwei Mao (Mao)
  2020-04-19  4:11 ` Dave Taht
  2020-04-21 14:36 ` kbuild test robot
  0 siblings, 2 replies; 5+ messages in thread
From: Jianwei Mao (Mao) @ 2020-04-19  3:33 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuznet, yoshfuji, kuba, maojianwei

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@maojianwei.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

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

* Re: [PATCH net-next] net: ipv6: support Application-aware IPv6 Network (APN6)
  2020-04-19  3:33 [PATCH net-next] net: ipv6: support Application-aware IPv6 Network (APN6) Jianwei Mao (Mao)
@ 2020-04-19  4:11 ` Dave Taht
  2020-04-19  6:02   ` Jianwei Mao (Mao)
  2020-04-21 14:36 ` kbuild test robot
  1 sibling, 1 reply; 5+ messages in thread
From: Dave Taht @ 2020-04-19  4:11 UTC (permalink / raw)
  To: Jianwei Mao (Mao); +Cc: netdev, davem, kuznet, yoshfuji, kuba, maojianwei

On Sat, Apr 18, 2020 at 8:39 PM Jianwei Mao (Mao)
<mao-linux@maojianwei.com> wrote:
>
> 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.

Well, it can declare that intent. As to delivering it....

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

That appears to be an expired draft. is there a replacement?

https://www.ietf.org/id/draft-li-apn6-framework-00.txt still seems current.

Where is the discussion of this taking in the ietf? 6man appears to
have nothing...

>
> 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@maojianwei.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



-- 
Make Music, Not War

Dave Täht
CTO, TekLibre, LLC
http://www.teklibre.com
Tel: 1-831-435-0729

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

* Re: [PATCH net-next] net: ipv6: support Application-aware IPv6 Network (APN6)
  2020-04-19  4:11 ` Dave Taht
@ 2020-04-19  6:02   ` Jianwei Mao (Mao)
       [not found]     ` <292d70b9-ea7c-4d0b-aec6-c0bf56848257.mao-linux@maojianwei.com>
  0 siblings, 1 reply; 5+ messages in thread
From: Jianwei Mao (Mao) @ 2020-04-19  6:02 UTC (permalink / raw)
  To: Dave Taht; +Cc: netdev, davem, kuznet, yoshfuji, kuba, maojianwei

Hi Dave,

Thanks for your comments, please see inline :)


On Sat, Apr 18, 2020 at 8:39 PM Jianwei Mao (Mao)
<mao-linux@maojianwei.com> wrote:
>
> 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.

Well, it can declare that intent. As to delivering it....

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

That appears to be an expired draft. is there a replacement?

https://www.ietf.org/id/draft-li-apn6-framework-00.txt still seems current.

Where is the discussion of this taking in the ietf? 6man appears to
have nothing...


Mao:
As to draft-li-6man-app-aware-ipv6-network, this ietf draft presents 
the definition and header format of IPv6 APN6 Hop-by-Hop(HBH) header.
Because there is no change for the format these months, so the draft isn't updated 
since last submission, and it shows expired in the web page.

This draft is discussing in ietf 6man workgroup, and it defines packet formats for IPv6, 
so we can mainly read it to implement APN6 for linux networking. :)

As for draft-li-apn6-framework, first of all, thanks for your searching and attention very much,
and this ietf draft presents a high-level-design for APN6, but not the detail for implementation.

Thanks,
Mao

>
> 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@maojianwei.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

-- 
Make Music, Not War

Dave Täht
CTO, TekLibre, LLC
http://www.teklibre.com
Tel: 1-831-435-0729

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

* Re: [PATCH net-next] net: ipv6: support Application-aware IPv6 Network (APN6)
       [not found]     ` <292d70b9-ea7c-4d0b-aec6-c0bf56848257.mao-linux@maojianwei.com>
@ 2020-04-19  6:20       ` Jianwei Mao (Mao)
  0 siblings, 0 replies; 5+ messages in thread
From: Jianwei Mao (Mao) @ 2020-04-19  6:20 UTC (permalink / raw)
  To: Dave Taht, mao-linux; +Cc: netdev, davem, kuznet, yoshfuji, kuba, maojianwei

Hi Dave,

Thanks for your comments, please see inline, with some complements added :)

(sorry for resend this email, because of rejection by netdev mail server)


On Sat, Apr 18, 2020 at 8:39 PM Jianwei Mao (Mao)
<mao-linux@maojianwei.com> wrote:
>
> 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.

Well, it can declare that intent. As to delivering it....

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

That appears to be an expired draft. is there a replacement?

https://www.ietf.org/id/draft-li-apn6-framework-00.txt still seems current.

Where is the discussion of this taking in the ietf? 6man appears to
have nothing...


Mao:
As to draft-li-6man-app-aware-ipv6-network, this ietf draft presents 
the definition and header format of IPv6 APN6 Hop-by-Hop(HBH) header.
Because there is no change for the format these months, so the draft isn't updated 
since last submission, and it shows expired in the web page without a replacement.

This draft is discussing in ietf 6man workgroup, and it defines packet formats for IPv6, 
so we can mainly read it to implement APN6 for linux networking. :)

As for draft-li-apn6-framework, first of all, thanks for your searching and attention very much,
and this ietf draft presents a high-level-design for APN6, but not the detail for implementation.
This draft is out of 6man, and is identified as apn6 workgroup, which may be preparing, btw,
it doesn't matter to us. :)


Expect your more reviews and comments,
Thanks,
Mao

>
> 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@maojianwei.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

-- 
Make Music, Not War

Dave Täht
CTO, TekLibre, LLC
http://www.teklibre.com
Tel: 1-831-435-0729

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

* Re: [PATCH net-next] net: ipv6: support Application-aware IPv6 Network (APN6)
  2020-04-19  3:33 [PATCH net-next] net: ipv6: support Application-aware IPv6 Network (APN6) Jianwei Mao (Mao)
  2020-04-19  4:11 ` Dave Taht
@ 2020-04-21 14:36 ` kbuild test robot
  1 sibling, 0 replies; 5+ messages in thread
From: kbuild test robot @ 2020-04-21 14:36 UTC (permalink / raw)
  To: Jianwei Mao (Mao), netdev, davem, kuznet, yoshfuji, kuba,
	maojianwei
  Cc: kbuild-all, davem, kuznet, yoshfuji, kuba

Hi "Jianwei,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]
[also build test WARNING on net/master ipsec/master linus/master v5.7-rc2 next-20200421]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Jianwei-Mao-Mao/net-ipv6-support-Application-aware-IPv6-Network-APN6/20200421-072711
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 82ebc889091a488b4dd95e682b3c3b889a50713c
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.1-191-gc51a0382-dirty
        make ARCH=x86_64 allmodconfig
        make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)

>> net/ipv6/ipv6_sockglue.c:171:13: sparse: sparse: incorrect type in assignment (different base types) @@    expected unsigned int [assigned] sla @@    got restrunsigned int [assigned] sla @@
>> net/ipv6/ipv6_sockglue.c:171:13: sparse:    expected unsigned int [assigned] sla
>> net/ipv6/ipv6_sockglue.c:171:13: sparse:    got restricted __be32 [usertype]
>> net/ipv6/ipv6_sockglue.c:172:16: sparse: sparse: incorrect type in assignment (different base types) @@    expected unsigned int [assigned] app_id @@    got restrunsigned int [assigned] app_id @@
>> net/ipv6/ipv6_sockglue.c:172:16: sparse:    expected unsigned int [assigned] app_id
   net/ipv6/ipv6_sockglue.c:172:16: sparse:    got restricted __be32 [usertype]
>> net/ipv6/ipv6_sockglue.c:173:17: sparse: sparse: incorrect type in assignment (different base types) @@    expected unsigned int [assigned] user_id @@    got restrunsigned int [assigned] user_id @@
>> net/ipv6/ipv6_sockglue.c:173:17: sparse:    expected unsigned int [assigned] user_id
   net/ipv6/ipv6_sockglue.c:173:17: sparse:    got restricted __be32 [usertype]
   net/ipv6/ipv6_sockglue.c:1143:33: sparse: sparse: incorrect type in assignment (different address spaces) @@    expected void *msg_control @@    got char [noderef] <asvoid *msg_control @@
   net/ipv6/ipv6_sockglue.c:1143:33: sparse:    expected void *msg_control
   net/ipv6/ipv6_sockglue.c:1143:33: sparse:    got char [noderef] <asn:1> *optval

vim +171 net/ipv6/ipv6_sockglue.c

   138	
   139	#define APN6_HBH_LEN 16
   140	#define APN6_HBH_HDR_LEN 4
   141	#define APN6_OPTION_TYPE 0x03
   142	#define APN6_OPTION_LEN (APN6_HBH_LEN - APN6_HBH_HDR_LEN)
   143	#define APN6_SLA_SIZE 4
   144	#define APN6_APPID_SIZE 4
   145	#define APN6_USERID_SIZE 4
   146	/* Return APN6 Hop-by-Hop(HBH) extension header */
   147	static void *generate_apn6_hopopts(char __user *optval, unsigned int optlen)
   148	{
   149		unsigned char *hbh;
   150		unsigned int sla, app_id, user_id;
   151	
   152		if (optlen < (sizeof(unsigned int) * 3))
   153			return NULL;
   154		else if (!optval)
   155			return NULL;
   156	
   157		if (get_user(sla, ((unsigned int __user *)optval)) ||
   158		    get_user(app_id, ((unsigned int __user *)optval) + 1) ||
   159		    get_user(user_id, ((unsigned int __user *)optval) + 2))
   160			return ERR_PTR(-EFAULT);
   161	
   162		pr_info("APN6: Get info: SLA:%08X AppID:%08X UserID:%08X",
   163			    sla, app_id, user_id);
   164	
   165		hbh = kzalloc(APN6_HBH_LEN, GFP_KERNEL);
   166		// hbh[0] is 0x0 now, and will be set natively when sending packets.
   167		hbh[1] = (APN6_HBH_LEN >> 3) - 1;
   168		hbh[2] = APN6_OPTION_TYPE;
   169		hbh[3] = APN6_OPTION_LEN;
   170	
 > 171		sla = htonl(sla);
 > 172		app_id = htonl(app_id);
 > 173		user_id = htonl(user_id);
   174		memcpy(hbh + APN6_HBH_HDR_LEN, &sla, APN6_SLA_SIZE);
   175		memcpy(hbh + APN6_HBH_HDR_LEN + APN6_SLA_SIZE, &app_id, APN6_APPID_SIZE);
   176		memcpy(hbh + APN6_HBH_HDR_LEN + APN6_SLA_SIZE + APN6_APPID_SIZE,
   177		       &user_id, APN6_USERID_SIZE);
   178	
   179		pr_info("APN6: Generate APN6 Hop-by-Hop extension header:\n"
   180				"%02X %02X %02X %02X\n"
   181				"%02X %02X %02X %02X\n"
   182				"%02X %02X %02X %02X\n"
   183				"%02X %02X %02X %02X",
   184				hbh[0], hbh[1], hbh[2], hbh[3],
   185				hbh[4], hbh[5], hbh[6], hbh[7],
   186				hbh[8], hbh[9], hbh[10], hbh[11],
   187				hbh[12], hbh[13], hbh[14], hbh[15]);
   188	
   189		return hbh;
   190	}
   191	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

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

end of thread, other threads:[~2020-04-21 14:37 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-04-19  3:33 [PATCH net-next] net: ipv6: support Application-aware IPv6 Network (APN6) Jianwei Mao (Mao)
2020-04-19  4:11 ` Dave Taht
2020-04-19  6:02   ` Jianwei Mao (Mao)
     [not found]     ` <292d70b9-ea7c-4d0b-aec6-c0bf56848257.mao-linux@maojianwei.com>
2020-04-19  6:20       ` Jianwei Mao (Mao)
2020-04-21 14:36 ` kbuild test robot

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).