diff options
Diffstat (limited to 'net/ipv6/seg6.c')
-rw-r--r-- | net/ipv6/seg6.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/net/ipv6/seg6.c b/net/ipv6/seg6.c index 4c7e0a27fa9c..d2f8138e5a73 100644 --- a/net/ipv6/seg6.c +++ b/net/ipv6/seg6.c @@ -25,10 +25,11 @@ #include <net/seg6_hmac.h> #endif -bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len) +bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len, bool reduced) { - int trailing; unsigned int tlv_offset; + int max_last_entry; + int trailing; if (srh->type != IPV6_SRCRT_TYPE_4) return false; @@ -36,8 +37,17 @@ bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len) if (((srh->hdrlen + 1) << 3) != len) return false; - if (srh->segments_left > srh->first_segment) + if (!reduced && srh->segments_left > srh->first_segment) { return false; + } else { + max_last_entry = (srh->hdrlen / 2) - 1; + + if (srh->first_segment > max_last_entry) + return false; + + if (srh->segments_left > srh->first_segment + 1) + return false; + } tlv_offset = sizeof(*srh) + ((srh->first_segment + 1) << 4); |