aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/exthdrs.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/exthdrs.c')
-rw-r--r--net/ipv6/exthdrs.c31
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
353looped_back: 352looped_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);