Commit cfbe9b00 authored by David S. Miller's avatar David S. Miller

Merge branch 'ipv6-ioam-encap'

Justin Iurman says:

====================
Support for the ip6ip6 encapsulation of IOAM

v2:
 - add prerequisite patches
 - keep uapi backwards compatible by adding two new attributes
 - add more comments to document the ioam6_iptunnel uapi

In the current implementation, IOAM can only be inserted directly (i.e., only
inside packets generated locally) by default, to be compliant with RFC8200.

This patch adds support for in-transit packets and provides the ip6ip6
encapsulation of IOAM (RFC8200 compliant). Therefore, three ioam6 encap modes
are defined:

 - inline: directly inserts IOAM inside packets (by default).

 - encap:  ip6ip6 encapsulation of IOAM inside packets.

 - auto:   either inline mode for packets generated locally or encap mode for
           in-transit packets.

With current iproute2 implementation, it is configured this way:

$ ip -6 r [...] encap ioam6 trace prealloc [...]

The old syntax does not change (for backwards compatibility) and implicitly uses
the inline mode. With the new syntax, an encap mode can be specified:

(inline mode)
$ ip -6 r [...] encap ioam6 mode inline trace prealloc [...]

(encap mode)
$ ip -6 r [...] encap ioam6 mode encap tundst fc00::2 trace prealloc [...]

(auto mode)
$ ip -6 r [...] encap ioam6 mode auto tundst fc00::2 trace prealloc [...]

A tunnel destination address must be configured when using the encap mode or the
auto mode.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9ac93627 bf77b140
...@@ -56,7 +56,8 @@ static inline struct ioam6_pernet_data *ioam6_pernet(struct net *net) ...@@ -56,7 +56,8 @@ static inline struct ioam6_pernet_data *ioam6_pernet(struct net *net)
struct ioam6_namespace *ioam6_namespace(struct net *net, __be16 id); struct ioam6_namespace *ioam6_namespace(struct net *net, __be16 id);
void ioam6_fill_trace_data(struct sk_buff *skb, void ioam6_fill_trace_data(struct sk_buff *skb,
struct ioam6_namespace *ns, struct ioam6_namespace *ns,
struct ioam6_trace_hdr *trace); struct ioam6_trace_hdr *trace,
bool is_input);
int ioam6_init(void); int ioam6_init(void);
void ioam6_exit(void); void ioam6_exit(void);
......
...@@ -9,9 +9,38 @@ ...@@ -9,9 +9,38 @@
#ifndef _UAPI_LINUX_IOAM6_IPTUNNEL_H #ifndef _UAPI_LINUX_IOAM6_IPTUNNEL_H
#define _UAPI_LINUX_IOAM6_IPTUNNEL_H #define _UAPI_LINUX_IOAM6_IPTUNNEL_H
/* Encap modes:
* - inline: direct insertion
* - encap: ip6ip6 encapsulation
* - auto: inline for local packets, encap for in-transit packets
*/
enum {
__IOAM6_IPTUNNEL_MODE_MIN,
IOAM6_IPTUNNEL_MODE_INLINE,
IOAM6_IPTUNNEL_MODE_ENCAP,
IOAM6_IPTUNNEL_MODE_AUTO,
__IOAM6_IPTUNNEL_MODE_MAX,
};
#define IOAM6_IPTUNNEL_MODE_MIN (__IOAM6_IPTUNNEL_MODE_MIN + 1)
#define IOAM6_IPTUNNEL_MODE_MAX (__IOAM6_IPTUNNEL_MODE_MAX - 1)
enum { enum {
IOAM6_IPTUNNEL_UNSPEC, IOAM6_IPTUNNEL_UNSPEC,
/* Encap mode */
IOAM6_IPTUNNEL_MODE, /* u8 */
/* Tunnel dst address.
* For encap,auto modes.
*/
IOAM6_IPTUNNEL_DST, /* struct in6_addr */
/* IOAM Trace Header */
IOAM6_IPTUNNEL_TRACE, /* struct ioam6_trace_hdr */ IOAM6_IPTUNNEL_TRACE, /* struct ioam6_trace_hdr */
__IOAM6_IPTUNNEL_MAX, __IOAM6_IPTUNNEL_MAX,
}; };
......
...@@ -332,10 +332,10 @@ config IPV6_IOAM6_LWTUNNEL ...@@ -332,10 +332,10 @@ config IPV6_IOAM6_LWTUNNEL
bool "IPv6: IOAM Pre-allocated Trace insertion support" bool "IPv6: IOAM Pre-allocated Trace insertion support"
depends on IPV6 depends on IPV6
select LWTUNNEL select LWTUNNEL
select DST_CACHE
help help
Support for the inline insertion of IOAM Pre-allocated Support for the insertion of IOAM Pre-allocated Trace
Trace Header (only on locally generated packets), using Header using the lightweight tunnels mechanism.
the lightweight tunnels mechanism.
If unsure, say N. If unsure, say N.
......
...@@ -979,7 +979,7 @@ static bool ipv6_hop_ioam(struct sk_buff *skb, int optoff) ...@@ -979,7 +979,7 @@ static bool ipv6_hop_ioam(struct sk_buff *skb, int optoff)
if (!skb_valid_dst(skb)) if (!skb_valid_dst(skb))
ip6_route_input(skb); ip6_route_input(skb);
ioam6_fill_trace_data(skb, ns, trace); ioam6_fill_trace_data(skb, ns, trace, true);
break; break;
default: default:
break; break;
......
...@@ -631,7 +631,7 @@ static void __ioam6_fill_trace_data(struct sk_buff *skb, ...@@ -631,7 +631,7 @@ static void __ioam6_fill_trace_data(struct sk_buff *skb,
struct ioam6_namespace *ns, struct ioam6_namespace *ns,
struct ioam6_trace_hdr *trace, struct ioam6_trace_hdr *trace,
struct ioam6_schema *sc, struct ioam6_schema *sc,
u8 sclen) u8 sclen, bool is_input)
{ {
struct __kernel_sock_timeval ts; struct __kernel_sock_timeval ts;
u64 raw64; u64 raw64;
...@@ -645,7 +645,7 @@ static void __ioam6_fill_trace_data(struct sk_buff *skb, ...@@ -645,7 +645,7 @@ static void __ioam6_fill_trace_data(struct sk_buff *skb,
/* hop_lim and node_id */ /* hop_lim and node_id */
if (trace->type.bit0) { if (trace->type.bit0) {
byte = ipv6_hdr(skb)->hop_limit; byte = ipv6_hdr(skb)->hop_limit;
if (skb->dev) if (is_input)
byte--; byte--;
raw32 = dev_net(skb_dst(skb)->dev)->ipv6.sysctl.ioam6_id; raw32 = dev_net(skb_dst(skb)->dev)->ipv6.sysctl.ioam6_id;
...@@ -730,7 +730,7 @@ static void __ioam6_fill_trace_data(struct sk_buff *skb, ...@@ -730,7 +730,7 @@ static void __ioam6_fill_trace_data(struct sk_buff *skb,
/* hop_lim and node_id (wide) */ /* hop_lim and node_id (wide) */
if (trace->type.bit8) { if (trace->type.bit8) {
byte = ipv6_hdr(skb)->hop_limit; byte = ipv6_hdr(skb)->hop_limit;
if (skb->dev) if (is_input)
byte--; byte--;
raw64 = dev_net(skb_dst(skb)->dev)->ipv6.sysctl.ioam6_id_wide; raw64 = dev_net(skb_dst(skb)->dev)->ipv6.sysctl.ioam6_id_wide;
...@@ -786,7 +786,8 @@ static void __ioam6_fill_trace_data(struct sk_buff *skb, ...@@ -786,7 +786,8 @@ static void __ioam6_fill_trace_data(struct sk_buff *skb,
/* called with rcu_read_lock() */ /* called with rcu_read_lock() */
void ioam6_fill_trace_data(struct sk_buff *skb, void ioam6_fill_trace_data(struct sk_buff *skb,
struct ioam6_namespace *ns, struct ioam6_namespace *ns,
struct ioam6_trace_hdr *trace) struct ioam6_trace_hdr *trace,
bool is_input)
{ {
struct ioam6_schema *sc; struct ioam6_schema *sc;
u8 sclen = 0; u8 sclen = 0;
...@@ -822,7 +823,7 @@ void ioam6_fill_trace_data(struct sk_buff *skb, ...@@ -822,7 +823,7 @@ void ioam6_fill_trace_data(struct sk_buff *skb,
return; return;
} }
__ioam6_fill_trace_data(skb, ns, trace, sc, sclen); __ioam6_fill_trace_data(skb, ns, trace, sc, sclen, is_input);
trace->remlen -= trace->nodelen + sclen; trace->remlen -= trace->nodelen + sclen;
} }
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment