Thread (4 messages) 4 messages, 3 authors, 2020-04-21

Re: [PATCH net-next] net: ipv6: support Application-aware IPv6 Network (APN6)

flat view

From: Dave Taht <hidden>
Date: 2020-04-19 04:11:46

On Sat, Apr 18, 2020 at 8:39 PM Jianwei Mao (Mao)
[off-list ref] 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...
quoted hunk ↗ jump to hunk
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 <redacted>
---
 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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help