uapi: IPv6 IOAM headers definition
authorJustin Iurman <justin.iurman@uliege.be>
Tue, 20 Jul 2021 19:42:56 +0000 (21:42 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 21 Jul 2021 15:14:33 +0000 (08:14 -0700)
This patch provides the IPv6 IOAM option header [1] as well as the IOAM
Trace header [2]. An IOAM option must be 4n-aligned. Here is an overview of
a Hop-by-Hop with an IOAM Trace option:

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Next header  |  Hdr Ext Len  |    Padding    |    Padding    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Option Type  |  Opt Data Len |    Reserved   |   IOAM Type   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Namespace-ID          | NodeLen | Flags | RemainingLen|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                IOAM-Trace-Type                |    Reserved   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<-+
|                                                               |  |
|                         node data [n]                         |  |
|                                                               |  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  D
|                                                               |  a
|                         node data [n-1]                       |  t
|                                                               |  a
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
~                             ...                               ~  S
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  p
|                                                               |  a
|                         node data [1]                         |  c
|                                                               |  e
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |
|                                                               |  |
|                         node data [0]                         |  |
|                                                               |  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<-+

The IOAM option header starts at "Option Type" and ends after "IOAM
Type". The IOAM Trace header starts at "Namespace-ID" and ends after
"IOAM-Trace-Type/Reserved".

IOAM Type: either Pre-allocated Trace (=0), Incremental Trace (=1),
Proof-of-Transit (=2) or Edge-to-Edge (=3). Note that both the
Pre-allocated Trace and the Incremental Trace look the same. The two
others are not implemented.

Namespace-ID: IOAM namespace identifier, not to be confused with network
namespaces. It adds further context to IOAM options and associated data,
and allows devices which are IOAM capable to determine whether IOAM
options must be processed or ignored. It can also be used by an operator
to distinguish different operational domains or to identify different
sets of devices.

NodeLen: Length of data added by each node. It depends on the Trace
Type.

Flags: Only the Overflow (O) flag for now. The O flag is set by a
transit node when there are not enough octets left to record its data.

RemainingLen: Remaining free space to record data.

IOAM-Trace-Type: Bit field where each bit corresponds to a specific kind
of IOAM data. See [2] for a detailed list.

  [1] https://tools.ietf.org/html/draft-ietf-ippm-ioam-ipv6-options
  [2] https://tools.ietf.org/html/draft-ietf-ippm-ioam-data

Signed-off-by: Justin Iurman <justin.iurman@uliege.be>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/uapi/linux/ioam6.h [new file with mode: 0644]

diff --git a/include/uapi/linux/ioam6.h b/include/uapi/linux/ioam6.h
new file mode 100644 (file)
index 0000000..2177e4e
--- /dev/null
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
+/*
+ *  IPv6 IOAM implementation
+ *
+ *  Author:
+ *  Justin Iurman <justin.iurman@uliege.be>
+ */
+
+#ifndef _UAPI_LINUX_IOAM6_H
+#define _UAPI_LINUX_IOAM6_H
+
+#include <asm/byteorder.h>
+#include <linux/types.h>
+
+/*
+ * IPv6 IOAM Option Header
+ */
+struct ioam6_hdr {
+       __u8 opt_type;
+       __u8 opt_len;
+       __u8 :8;                                /* reserved */
+#define IOAM6_TYPE_PREALLOC 0
+       __u8 type;
+} __attribute__((packed));
+
+/*
+ * IOAM Trace Header
+ */
+struct ioam6_trace_hdr {
+       __be16  namespace_id;
+
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+
+       __u8    :1,                             /* unused */
+               :1,                             /* unused */
+               overflow:1,
+               nodelen:5;
+
+       __u8    remlen:7,
+               :1;                             /* unused */
+
+       union {
+               __be32 type_be32;
+
+               struct {
+                       __u32   bit7:1,
+                               bit6:1,
+                               bit5:1,
+                               bit4:1,
+                               bit3:1,
+                               bit2:1,
+                               bit1:1,
+                               bit0:1,
+                               bit15:1,        /* unused */
+                               bit14:1,        /* unused */
+                               bit13:1,        /* unused */
+                               bit12:1,        /* unused */
+                               bit11:1,
+                               bit10:1,
+                               bit9:1,
+                               bit8:1,
+                               bit23:1,        /* reserved */
+                               bit22:1,
+                               bit21:1,        /* unused */
+                               bit20:1,        /* unused */
+                               bit19:1,        /* unused */
+                               bit18:1,        /* unused */
+                               bit17:1,        /* unused */
+                               bit16:1,        /* unused */
+                               :8;             /* reserved */
+               } type;
+       };
+
+#elif defined(__BIG_ENDIAN_BITFIELD)
+
+       __u8    nodelen:5,
+               overflow:1,
+               :1,                             /* unused */
+               :1;                             /* unused */
+
+       __u8    :1,                             /* unused */
+               remlen:7;
+
+       union {
+               __be32 type_be32;
+
+               struct {
+                       __u32   bit0:1,
+                               bit1:1,
+                               bit2:1,
+                               bit3:1,
+                               bit4:1,
+                               bit5:1,
+                               bit6:1,
+                               bit7:1,
+                               bit8:1,
+                               bit9:1,
+                               bit10:1,
+                               bit11:1,
+                               bit12:1,        /* unused */
+                               bit13:1,        /* unused */
+                               bit14:1,        /* unused */
+                               bit15:1,        /* unused */
+                               bit16:1,        /* unused */
+                               bit17:1,        /* unused */
+                               bit18:1,        /* unused */
+                               bit19:1,        /* unused */
+                               bit20:1,        /* unused */
+                               bit21:1,        /* unused */
+                               bit22:1,
+                               bit23:1,        /* reserved */
+                               :8;             /* reserved */
+               } type;
+       };
+
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+
+       __u8    data[0];
+} __attribute__((packed));
+
+#endif /* _UAPI_LINUX_IOAM6_H */