summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/ipv6/seg6_local.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c
index 9c1a885ee482..7ff54db73a48 100644
--- a/net/ipv6/seg6_local.c
+++ b/net/ipv6/seg6_local.c
@@ -62,17 +62,23 @@ static struct seg6_local_lwt *seg6_local_lwtunnel(struct lwtunnel_state *lwt)
static struct ipv6_sr_hdr *get_srh(struct sk_buff *skb)
{
struct ipv6_sr_hdr *srh;
- struct ipv6hdr *hdr;
- int len;
+ int len, srhoff = 0;
+
+ if (ipv6_find_hdr(skb, &srhoff, IPPROTO_ROUTING, NULL, NULL) < 0)
+ return NULL;
+
+ if (!pskb_may_pull(skb, srhoff + sizeof(*srh)))
+ return NULL;
+
+ srh = (struct ipv6_sr_hdr *)(skb->data + srhoff);
- hdr = ipv6_hdr(skb);
- if (hdr->nexthdr != IPPROTO_ROUTING)
+ /* make sure it's a Segment Routing header (Routing Type 4) */
+ if (srh->type != IPV6_SRCRT_TYPE_4)
return NULL;
- srh = (struct ipv6_sr_hdr *)(hdr + 1);
len = (srh->hdrlen + 1) << 3;
- if (!pskb_may_pull(skb, sizeof(*hdr) + len))
+ if (!pskb_may_pull(skb, srhoff + len))
return NULL;
if (!seg6_validate_srh(srh, len))