Skip to content

Commit 7c804e9

Browse files
committed
Merge branch 'ipv6-ioam'
Justin Iurman says: ==================== Support for the IOAM Pre-allocated Trace with IPv6 v5: - Refine types, min/max and default values for new sysctls - Introduce a "_wide" sysctl for each "ioam6_id" sysctl - Add more validation on headers before processing data - RCU for sc <> ns pointers + appropriate accessors - Generic Netlink policies are now per op, not per family anymore - Address other comments/remarks from Jakub (thanks again) - Revert "__packed" to "__attribute__((packed))" for uapi headers - Add tests to cover the functionality added, as requested by David Ahern v4: - Address warnings from checkpatch (ignore errors related to unnamed bitfields in the first patch) - Use of hweight32 (thanks Jakub) - Remove inline keyword from static functions in C files and let the compiler decide what to do (thanks Jakub) v3: - Fix warning "unused label 'out_unregister_genl'" by adding conditional macro - Fix lwtunnel output redirect bug: dst cache useless in this case, use orig_output instead v2: - Fix warning with static for __ioam6_fill_trace_data - Fix sparse warning with __force when casting __be64 to __be32 - Fix unchecked dereference when removing IOAM namespaces or schemas - exthdrs.c: Don't drop by default (now: ignore) to match the act bits "00" - Add control plane support for the inline insertion (lwtunnel) - Provide uapi structures - Use __net_timestamp if skb->tstamp is empty - Add note about the temporary IANA allocation - Remove support for "removable" TLVs - Remove support for virtual/anonymous tunnel decapsulation In-situ Operations, Administration, and Maintenance (IOAM) records operational and telemetry information in a packet while it traverses a path between two points in an IOAM domain. It is defined in draft-ietf-ippm-ioam-data [1]. IOAM data fields can be encapsulated into a variety of protocols. The IPv6 encapsulation is defined in draft-ietf-ippm-ioam-ipv6-options [2], via extension headers. IOAM can be used to complement OAM mechanisms based on e.g. ICMP or other types of probe packets. This patchset implements support for the Pre-allocated Trace, carried by a Hop-by-Hop. Therefore, a new IPv6 Hop-by-Hop TLV option is introduced, see IANA [3]. The three other IOAM options are not included in this patchset (Incremental Trace, Proof-of-Transit and Edge-to-Edge). The main idea behind the IOAM Pre-allocated Trace is that a node pre-allocates some room in packets for IOAM data. Then, each IOAM node on the path will insert its data. There exist several interesting use- cases, e.g. Fast failure detection/isolation or Smart service selection. Another killer use-case is what we have called Cross-Layer Telemetry, see the demo video on its repository [4], that aims to make the entire stack (L2/L3 -> L7) visible for distributed tracing tools (e.g. Jaeger), instead of the current L5 -> L7 limited view. So, basically, this is a nice feature for the Linux Kernel. This patchset also provides support for the control plane part, but only for the inline insertion (host-to-host use case), through lightweight tunnels. Indeed, for in-transit traffic, the solution is to have an IPv6-in-IPv6 encapsulation, which brings some difficulties and still requires a little bit of work and discussion (ie anonymous tunnel decapsulation and multi egress resolution). - Patch 1: IPv6 IOAM headers definition - Patch 2: Data plane support for Pre-allocated Trace - Patch 3: IOAM Generic Netlink API - Patch 4: Support for IOAM injection with lwtunnels - Patch 5: Documentation for new IOAM sysctls - Patch 6: Test for the IOAM insertion with IPv6 [1] https://tools.ietf.org/html/draft-ietf-ippm-ioam-data [2] https://tools.ietf.org/html/draft-ietf-ippm-ioam-ipv6-options [3] https://www.iana.org/assignments/ipv6-parameters/ipv6-parameters.xhtml#ipv6-parameters-2 [4] https://github.com/iurmanj/cross-layer-telemetry ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 71f4f89 + 968691c commit 7c804e9

File tree

27 files changed

+2393
-1
lines changed

27 files changed

+2393
-1
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
3+
=====================
4+
IOAM6 Sysfs variables
5+
=====================
6+
7+
8+
/proc/sys/net/conf/<iface>/ioam6_* variables:
9+
=============================================
10+
11+
ioam6_enabled - BOOL
12+
Accept (= enabled) or ignore (= disabled) IPv6 IOAM options on ingress
13+
for this interface.
14+
15+
* 0 - disabled (default)
16+
* 1 - enabled
17+
18+
ioam6_id - SHORT INTEGER
19+
Define the IOAM id of this interface.
20+
21+
Default is ~0.
22+
23+
ioam6_id_wide - INTEGER
24+
Define the wide IOAM id of this interface.
25+
26+
Default is ~0.

Documentation/networking/ip-sysctl.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,6 +1926,23 @@ fib_notify_on_flag_change - INTEGER
19261926
- 1 - Emit notifications.
19271927
- 2 - Emit notifications only for RTM_F_OFFLOAD_FAILED flag change.
19281928

1929+
ioam6_id - INTEGER
1930+
Define the IOAM id of this node. Uses only 24 bits out of 32 in total.
1931+
1932+
Min: 0
1933+
Max: 0xFFFFFF
1934+
1935+
Default: 0xFFFFFF
1936+
1937+
ioam6_id_wide - LONG INTEGER
1938+
Define the wide IOAM id of this node. Uses only 56 bits out of 64 in
1939+
total. Can be different from ioam6_id.
1940+
1941+
Min: 0
1942+
Max: 0xFFFFFFFFFFFFFF
1943+
1944+
Default: 0xFFFFFFFFFFFFFF
1945+
19291946
IPv6 Fragmentation:
19301947

19311948
ip6frag_high_thresh - INTEGER

include/linux/ioam6.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* SPDX-License-Identifier: GPL-2.0+ */
2+
/*
3+
* IPv6 IOAM
4+
*
5+
* Author:
6+
* Justin Iurman <[email protected]>
7+
*/
8+
#ifndef _LINUX_IOAM6_H
9+
#define _LINUX_IOAM6_H
10+
11+
#include <uapi/linux/ioam6.h>
12+
13+
#endif /* _LINUX_IOAM6_H */

include/linux/ioam6_genl.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* SPDX-License-Identifier: GPL-2.0+ */
2+
/*
3+
* IPv6 IOAM Generic Netlink API
4+
*
5+
* Author:
6+
* Justin Iurman <[email protected]>
7+
*/
8+
#ifndef _LINUX_IOAM6_GENL_H
9+
#define _LINUX_IOAM6_GENL_H
10+
11+
#include <uapi/linux/ioam6_genl.h>
12+
13+
#endif /* _LINUX_IOAM6_GENL_H */

include/linux/ioam6_iptunnel.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* SPDX-License-Identifier: GPL-2.0+ */
2+
/*
3+
* IPv6 IOAM Lightweight Tunnel API
4+
*
5+
* Author:
6+
* Justin Iurman <[email protected]>
7+
*/
8+
#ifndef _LINUX_IOAM6_IPTUNNEL_H
9+
#define _LINUX_IOAM6_IPTUNNEL_H
10+
11+
#include <uapi/linux/ioam6_iptunnel.h>
12+
13+
#endif /* _LINUX_IOAM6_IPTUNNEL_H */

include/linux/ipv6.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ struct ipv6_devconf {
7676
__s32 disable_policy;
7777
__s32 ndisc_tclass;
7878
__s32 rpl_seg_enabled;
79+
__u32 ioam6_id;
80+
__u32 ioam6_id_wide;
81+
__u8 ioam6_enabled;
7982

8083
struct ctl_table_header *sysctl_header;
8184
};

include/net/ioam6.h

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/* SPDX-License-Identifier: GPL-2.0+ */
2+
/*
3+
* IPv6 IOAM implementation
4+
*
5+
* Author:
6+
* Justin Iurman <[email protected]>
7+
*/
8+
9+
#ifndef _NET_IOAM6_H
10+
#define _NET_IOAM6_H
11+
12+
#include <linux/net.h>
13+
#include <linux/ipv6.h>
14+
#include <linux/ioam6.h>
15+
#include <linux/rhashtable-types.h>
16+
17+
struct ioam6_namespace {
18+
struct rhash_head head;
19+
struct rcu_head rcu;
20+
21+
struct ioam6_schema __rcu *schema;
22+
23+
__be16 id;
24+
__be32 data;
25+
__be64 data_wide;
26+
};
27+
28+
struct ioam6_schema {
29+
struct rhash_head head;
30+
struct rcu_head rcu;
31+
32+
struct ioam6_namespace __rcu *ns;
33+
34+
u32 id;
35+
int len;
36+
__be32 hdr;
37+
38+
u8 data[0];
39+
};
40+
41+
struct ioam6_pernet_data {
42+
struct mutex lock;
43+
struct rhashtable namespaces;
44+
struct rhashtable schemas;
45+
};
46+
47+
static inline struct ioam6_pernet_data *ioam6_pernet(struct net *net)
48+
{
49+
#if IS_ENABLED(CONFIG_IPV6)
50+
return net->ipv6.ioam6_data;
51+
#else
52+
return NULL;
53+
#endif
54+
}
55+
56+
struct ioam6_namespace *ioam6_namespace(struct net *net, __be16 id);
57+
void ioam6_fill_trace_data(struct sk_buff *skb,
58+
struct ioam6_namespace *ns,
59+
struct ioam6_trace_hdr *trace);
60+
61+
int ioam6_init(void);
62+
void ioam6_exit(void);
63+
64+
int ioam6_iptunnel_init(void);
65+
void ioam6_iptunnel_exit(void);
66+
67+
#endif /* _NET_IOAM6_H */

include/net/netns/ipv6.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ struct netns_sysctl_ipv6 {
5151
int max_dst_opts_len;
5252
int max_hbh_opts_len;
5353
int seg6_flowlabel;
54+
u32 ioam6_id;
55+
u64 ioam6_id_wide;
5456
bool skip_notify_on_dev_down;
5557
u8 fib_notify_on_flag_change;
5658
};
@@ -110,6 +112,7 @@ struct netns_ipv6 {
110112
spinlock_t lock;
111113
u32 seq;
112114
} ip6addrlbl_table;
115+
struct ioam6_pernet_data *ioam6_data;
113116
};
114117

115118
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)

include/uapi/linux/in6.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ struct in6_flowlabel_req {
145145
#define IPV6_TLV_PADN 1
146146
#define IPV6_TLV_ROUTERALERT 5
147147
#define IPV6_TLV_CALIPSO 7 /* RFC 5570 */
148+
#define IPV6_TLV_IOAM 49 /* TEMPORARY IANA allocation for IOAM */
148149
#define IPV6_TLV_JUMBO 194
149150
#define IPV6_TLV_HAO 201 /* home address option */
150151

include/uapi/linux/ioam6.h

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
2+
/*
3+
* IPv6 IOAM implementation
4+
*
5+
* Author:
6+
* Justin Iurman <[email protected]>
7+
*/
8+
9+
#ifndef _UAPI_LINUX_IOAM6_H
10+
#define _UAPI_LINUX_IOAM6_H
11+
12+
#include <asm/byteorder.h>
13+
#include <linux/types.h>
14+
15+
#define IOAM6_U16_UNAVAILABLE U16_MAX
16+
#define IOAM6_U32_UNAVAILABLE U32_MAX
17+
#define IOAM6_U64_UNAVAILABLE U64_MAX
18+
19+
#define IOAM6_DEFAULT_ID (IOAM6_U32_UNAVAILABLE >> 8)
20+
#define IOAM6_DEFAULT_ID_WIDE (IOAM6_U64_UNAVAILABLE >> 8)
21+
#define IOAM6_DEFAULT_IF_ID IOAM6_U16_UNAVAILABLE
22+
#define IOAM6_DEFAULT_IF_ID_WIDE IOAM6_U32_UNAVAILABLE
23+
24+
/*
25+
* IPv6 IOAM Option Header
26+
*/
27+
struct ioam6_hdr {
28+
__u8 opt_type;
29+
__u8 opt_len;
30+
__u8 :8; /* reserved */
31+
#define IOAM6_TYPE_PREALLOC 0
32+
__u8 type;
33+
} __attribute__((packed));
34+
35+
/*
36+
* IOAM Trace Header
37+
*/
38+
struct ioam6_trace_hdr {
39+
__be16 namespace_id;
40+
41+
#if defined(__LITTLE_ENDIAN_BITFIELD)
42+
43+
__u8 :1, /* unused */
44+
:1, /* unused */
45+
overflow:1,
46+
nodelen:5;
47+
48+
__u8 remlen:7,
49+
:1; /* unused */
50+
51+
union {
52+
__be32 type_be32;
53+
54+
struct {
55+
__u32 bit7:1,
56+
bit6:1,
57+
bit5:1,
58+
bit4:1,
59+
bit3:1,
60+
bit2:1,
61+
bit1:1,
62+
bit0:1,
63+
bit15:1, /* unused */
64+
bit14:1, /* unused */
65+
bit13:1, /* unused */
66+
bit12:1, /* unused */
67+
bit11:1,
68+
bit10:1,
69+
bit9:1,
70+
bit8:1,
71+
bit23:1, /* reserved */
72+
bit22:1,
73+
bit21:1, /* unused */
74+
bit20:1, /* unused */
75+
bit19:1, /* unused */
76+
bit18:1, /* unused */
77+
bit17:1, /* unused */
78+
bit16:1, /* unused */
79+
:8; /* reserved */
80+
} type;
81+
};
82+
83+
#elif defined(__BIG_ENDIAN_BITFIELD)
84+
85+
__u8 nodelen:5,
86+
overflow:1,
87+
:1, /* unused */
88+
:1; /* unused */
89+
90+
__u8 :1, /* unused */
91+
remlen:7;
92+
93+
union {
94+
__be32 type_be32;
95+
96+
struct {
97+
__u32 bit0:1,
98+
bit1:1,
99+
bit2:1,
100+
bit3:1,
101+
bit4:1,
102+
bit5:1,
103+
bit6:1,
104+
bit7:1,
105+
bit8:1,
106+
bit9:1,
107+
bit10:1,
108+
bit11:1,
109+
bit12:1, /* unused */
110+
bit13:1, /* unused */
111+
bit14:1, /* unused */
112+
bit15:1, /* unused */
113+
bit16:1, /* unused */
114+
bit17:1, /* unused */
115+
bit18:1, /* unused */
116+
bit19:1, /* unused */
117+
bit20:1, /* unused */
118+
bit21:1, /* unused */
119+
bit22:1,
120+
bit23:1, /* reserved */
121+
:8; /* reserved */
122+
} type;
123+
};
124+
125+
#else
126+
#error "Please fix <asm/byteorder.h>"
127+
#endif
128+
129+
#define IOAM6_TRACE_DATA_SIZE_MAX 244
130+
__u8 data[0];
131+
} __attribute__((packed));
132+
133+
#endif /* _UAPI_LINUX_IOAM6_H */

0 commit comments

Comments
 (0)