summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/net/ioam6.h2
-rw-r--r--net/ipv6/exthdrs.c5
-rw-r--r--net/ipv6/ioam6.c14
-rw-r--r--net/ipv6/ioam6_iptunnel.c10
4 files changed, 22 insertions, 9 deletions
diff --git a/include/net/ioam6.h b/include/net/ioam6.h
index 781d2d8b2f29..3f99eb445de6 100644
--- a/include/net/ioam6.h
+++ b/include/net/ioam6.h
@@ -59,6 +59,8 @@ void ioam6_fill_trace_data(struct sk_buff *skb,
struct ioam6_trace_hdr *trace,
bool is_input);
+u8 ioam6_trace_compute_nodelen(u32 trace_type);
+
int ioam6_init(void);
void ioam6_exit(void);
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index d0aaa35fc2e9..676284b6efe8 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -938,6 +938,11 @@ static bool ipv6_hop_ioam(struct sk_buff *skb, int optoff)
if (hdr->opt_len < 2 + sizeof(*trace) + trace->remlen * 4)
goto drop;
+ /* Inconsistent Pre-allocated Trace header */
+ if (trace->nodelen !=
+ ioam6_trace_compute_nodelen(be32_to_cpu(trace->type_be32)))
+ goto drop;
+
/* Ignore if the IOAM namespace is unknown */
ns = ioam6_namespace(ipv6_skb_net(skb), trace->namespace_id);
if (!ns)
diff --git a/net/ipv6/ioam6.c b/net/ipv6/ioam6.c
index 571f0e4d9cf3..a35b6fdbc93e 100644
--- a/net/ipv6/ioam6.c
+++ b/net/ipv6/ioam6.c
@@ -630,6 +630,20 @@ struct ioam6_namespace *ioam6_namespace(struct net *net, __be16 id)
return rhashtable_lookup_fast(&nsdata->namespaces, &id, rht_ns_params);
}
+#define IOAM6_MASK_SHORT_FIELDS 0xff1ffc00
+#define IOAM6_MASK_WIDE_FIELDS 0x00e00000
+
+u8 ioam6_trace_compute_nodelen(u32 trace_type)
+{
+ u8 nodelen = hweight32(trace_type & IOAM6_MASK_SHORT_FIELDS)
+ * (sizeof(__be32) / 4);
+
+ nodelen += hweight32(trace_type & IOAM6_MASK_WIDE_FIELDS)
+ * (sizeof(__be64) / 4);
+
+ return nodelen;
+}
+
static void __ioam6_fill_trace_data(struct sk_buff *skb,
struct ioam6_namespace *ns,
struct ioam6_trace_hdr *trace,
diff --git a/net/ipv6/ioam6_iptunnel.c b/net/ipv6/ioam6_iptunnel.c
index a5cfc5b0b206..3a6065faaf9b 100644
--- a/net/ipv6/ioam6_iptunnel.c
+++ b/net/ipv6/ioam6_iptunnel.c
@@ -22,9 +22,6 @@
#include <net/ip6_route.h>
#include <net/addrconf.h>
-#define IOAM6_MASK_SHORT_FIELDS 0xff100000
-#define IOAM6_MASK_WIDE_FIELDS 0xe00000
-
struct ioam6_lwt_encap {
struct ipv6_hopopt_hdr eh;
u8 pad[2]; /* 2-octet padding for 4n-alignment */
@@ -88,13 +85,8 @@ static bool ioam6_validate_trace_hdr(struct ioam6_trace_hdr *trace)
trace->type.bit21)
return false;
- trace->nodelen = 0;
fields = be32_to_cpu(trace->type_be32);
-
- trace->nodelen += hweight32(fields & IOAM6_MASK_SHORT_FIELDS)
- * (sizeof(__be32) / 4);
- trace->nodelen += hweight32(fields & IOAM6_MASK_WIDE_FIELDS)
- * (sizeof(__be64) / 4);
+ trace->nodelen = ioam6_trace_compute_nodelen(fields);
return true;
}