summaryrefslogtreecommitdiff
path: root/net/ipv6/ioam6.c
diff options
context:
space:
mode:
authorJustin Iurman <justin.iurman@uliege.be>2021-07-20 22:42:59 +0300
committerDavid S. Miller <davem@davemloft.net>2021-07-21 18:14:33 +0300
commit3edede08ff37c6a9370510508d5eeb54890baf47 (patch)
tree290995c14ae43eae8a0e6ee11604d81f6a7c6972 /net/ipv6/ioam6.c
parent8c6f6fa6772696be0c047a711858084b38763728 (diff)
downloadlinux-3edede08ff37c6a9370510508d5eeb54890baf47.tar.xz
ipv6: ioam: Support for IOAM injection with lwtunnels
Add support for the IOAM inline insertion (only for the host-to-host use case) which is per-route configured with lightweight tunnels. The target is iproute2 and the patch is ready. It will be posted as soon as this patchset is merged. Here is an overview: $ ip -6 ro ad fc00::1/128 encap ioam6 trace type 0x800000 ns 1 size 12 dev eth0 This example configures an IOAM Pre-allocated Trace option attached to the fc00::1/128 prefix. The IOAM namespace (ns) is 1, the size of the pre-allocated trace data block is 12 octets (size) and only the first IOAM data (bit 0: hop_limit + node id) is included in the trace (type) represented as a bitfield. The reason why the in-transit (IPv6-in-IPv6 encapsulation) use case is not implemented is explained on the patchset cover. Signed-off-by: Justin Iurman <justin.iurman@uliege.be> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ioam6.c')
-rw-r--r--net/ipv6/ioam6.c44
1 files changed, 32 insertions, 12 deletions
diff --git a/net/ipv6/ioam6.c b/net/ipv6/ioam6.c
index ba59671f32b8..5e8961004832 100644
--- a/net/ipv6/ioam6.c
+++ b/net/ipv6/ioam6.c
@@ -648,7 +648,7 @@ static void __ioam6_fill_trace_data(struct sk_buff *skb,
if (skb->dev)
byte--;
- raw32 = dev_net(skb->dev)->ipv6.sysctl.ioam6_id;
+ raw32 = dev_net(skb_dst(skb)->dev)->ipv6.sysctl.ioam6_id;
*(__be32 *)data = cpu_to_be32((byte << 24) | raw32);
data += sizeof(__be32);
@@ -675,24 +675,31 @@ static void __ioam6_fill_trace_data(struct sk_buff *skb,
/* timestamp seconds */
if (trace->type.bit2) {
- if (!skb->tstamp)
- __net_timestamp(skb);
-
- skb_get_new_timestamp(skb, &ts);
+ if (!skb->dev) {
+ *(__be32 *)data = cpu_to_be32(IOAM6_U32_UNAVAILABLE);
+ } else {
+ if (!skb->tstamp)
+ __net_timestamp(skb);
- *(__be32 *)data = cpu_to_be32((u32)ts.tv_sec);
+ skb_get_new_timestamp(skb, &ts);
+ *(__be32 *)data = cpu_to_be32((u32)ts.tv_sec);
+ }
data += sizeof(__be32);
}
/* timestamp subseconds */
if (trace->type.bit3) {
- if (!skb->tstamp)
- __net_timestamp(skb);
+ if (!skb->dev) {
+ *(__be32 *)data = cpu_to_be32(IOAM6_U32_UNAVAILABLE);
+ } else {
+ if (!skb->tstamp)
+ __net_timestamp(skb);
- if (!trace->type.bit2)
- skb_get_new_timestamp(skb, &ts);
+ if (!trace->type.bit2)
+ skb_get_new_timestamp(skb, &ts);
- *(__be32 *)data = cpu_to_be32((u32)ts.tv_usec);
+ *(__be32 *)data = cpu_to_be32((u32)ts.tv_usec);
+ }
data += sizeof(__be32);
}
@@ -726,7 +733,7 @@ static void __ioam6_fill_trace_data(struct sk_buff *skb,
if (skb->dev)
byte--;
- raw64 = dev_net(skb->dev)->ipv6.sysctl.ioam6_id_wide;
+ raw64 = dev_net(skb_dst(skb)->dev)->ipv6.sysctl.ioam6_id_wide;
*(__be64 *)data = cpu_to_be64(((u64)byte << 56) | raw64);
data += sizeof(__be64);
@@ -874,10 +881,20 @@ int __init ioam6_init(void)
if (err)
goto out_unregister_pernet_subsys;
+#ifdef CONFIG_IPV6_IOAM6_LWTUNNEL
+ err = ioam6_iptunnel_init();
+ if (err)
+ goto out_unregister_genl;
+#endif
+
pr_info("In-situ OAM (IOAM) with IPv6\n");
out:
return err;
+#ifdef CONFIG_IPV6_IOAM6_LWTUNNEL
+out_unregister_genl:
+ genl_unregister_family(&ioam6_genl_family);
+#endif
out_unregister_pernet_subsys:
unregister_pernet_subsys(&ioam6_net_ops);
goto out;
@@ -885,6 +902,9 @@ out_unregister_pernet_subsys:
void ioam6_exit(void)
{
+#ifdef CONFIG_IPV6_IOAM6_LWTUNNEL
+ ioam6_iptunnel_exit();
+#endif
genl_unregister_family(&ioam6_genl_family);
unregister_pernet_subsys(&ioam6_net_ops);
}