diff options
Diffstat (limited to 'net/ipv6/exthdrs.c')
-rw-r--r-- | net/ipv6/exthdrs.c | 31 |
1 files changed, 3 insertions, 28 deletions
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index e4198502fd98..275cac628a95 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -327,7 +327,6 @@ static int ipv6_srh_rcv(struct sk_buff *skb) | |||
327 | struct ipv6_sr_hdr *hdr; | 327 | struct ipv6_sr_hdr *hdr; |
328 | struct inet6_dev *idev; | 328 | struct inet6_dev *idev; |
329 | struct in6_addr *addr; | 329 | struct in6_addr *addr; |
330 | bool cleanup = false; | ||
331 | int accept_seg6; | 330 | int accept_seg6; |
332 | 331 | ||
333 | hdr = (struct ipv6_sr_hdr *)skb_transport_header(skb); | 332 | hdr = (struct ipv6_sr_hdr *)skb_transport_header(skb); |
@@ -351,11 +350,7 @@ static int ipv6_srh_rcv(struct sk_buff *skb) | |||
351 | #endif | 350 | #endif |
352 | 351 | ||
353 | looped_back: | 352 | looped_back: |
354 | if (hdr->segments_left > 0) { | 353 | if (hdr->segments_left == 0) { |
355 | if (hdr->nexthdr != NEXTHDR_IPV6 && hdr->segments_left == 1 && | ||
356 | sr_has_cleanup(hdr)) | ||
357 | cleanup = true; | ||
358 | } else { | ||
359 | if (hdr->nexthdr == NEXTHDR_IPV6) { | 354 | if (hdr->nexthdr == NEXTHDR_IPV6) { |
360 | int offset = (hdr->hdrlen + 1) << 3; | 355 | int offset = (hdr->hdrlen + 1) << 3; |
361 | 356 | ||
@@ -418,21 +413,6 @@ looped_back: | |||
418 | 413 | ||
419 | ipv6_hdr(skb)->daddr = *addr; | 414 | ipv6_hdr(skb)->daddr = *addr; |
420 | 415 | ||
421 | if (cleanup) { | ||
422 | int srhlen = (hdr->hdrlen + 1) << 3; | ||
423 | int nh = hdr->nexthdr; | ||
424 | |||
425 | skb_pull_rcsum(skb, sizeof(struct ipv6hdr) + srhlen); | ||
426 | memmove(skb_network_header(skb) + srhlen, | ||
427 | skb_network_header(skb), | ||
428 | (unsigned char *)hdr - skb_network_header(skb)); | ||
429 | skb->network_header += srhlen; | ||
430 | ipv6_hdr(skb)->nexthdr = nh; | ||
431 | ipv6_hdr(skb)->payload_len = htons(skb->len - | ||
432 | sizeof(struct ipv6hdr)); | ||
433 | skb_push_rcsum(skb, sizeof(struct ipv6hdr)); | ||
434 | } | ||
435 | |||
436 | skb_dst_drop(skb); | 416 | skb_dst_drop(skb); |
437 | 417 | ||
438 | ip6_route_input(skb); | 418 | ip6_route_input(skb); |
@@ -453,13 +433,8 @@ looped_back: | |||
453 | } | 433 | } |
454 | ipv6_hdr(skb)->hop_limit--; | 434 | ipv6_hdr(skb)->hop_limit--; |
455 | 435 | ||
456 | /* be sure that srh is still present before reinjecting */ | 436 | skb_pull(skb, sizeof(struct ipv6hdr)); |
457 | if (!cleanup) { | 437 | goto looped_back; |
458 | skb_pull(skb, sizeof(struct ipv6hdr)); | ||
459 | goto looped_back; | ||
460 | } | ||
461 | skb_set_transport_header(skb, sizeof(struct ipv6hdr)); | ||
462 | IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); | ||
463 | } | 438 | } |
464 | 439 | ||
465 | dst_input(skb); | 440 | dst_input(skb); |