diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/datagram.c | 3 | ||||
-rw-r--r-- | net/ipv6/exthdrs.c | 78 | ||||
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 3 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 20 |
4 files changed, 2 insertions, 102 deletions
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index ba1386dd4168..fe0f49024a0a 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -657,11 +657,10 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl, | |||
657 | rthdr = (struct ipv6_rt_hdr *)CMSG_DATA(cmsg); | 657 | rthdr = (struct ipv6_rt_hdr *)CMSG_DATA(cmsg); |
658 | 658 | ||
659 | switch (rthdr->type) { | 659 | switch (rthdr->type) { |
660 | case IPV6_SRCRT_TYPE_0: | ||
661 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 660 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) |
662 | case IPV6_SRCRT_TYPE_2: | 661 | case IPV6_SRCRT_TYPE_2: |
663 | #endif | ||
664 | break; | 662 | break; |
663 | #endif | ||
665 | default: | 664 | default: |
666 | err = -EINVAL; | 665 | err = -EINVAL; |
667 | goto exit_f; | 666 | goto exit_f; |
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index fc3a961fc5ba..c82d4d49f71f 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -427,18 +427,6 @@ looped_back: | |||
427 | } | 427 | } |
428 | 428 | ||
429 | switch (hdr->type) { | 429 | switch (hdr->type) { |
430 | case IPV6_SRCRT_TYPE_0: | ||
431 | if (accept_source_route <= 0) | ||
432 | goto unknown_rh; | ||
433 | if (hdr->hdrlen & 0x01) { | ||
434 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | ||
435 | IPSTATS_MIB_INHDRERRORS); | ||
436 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, | ||
437 | ((&hdr->hdrlen) - | ||
438 | skb_network_header(skb))); | ||
439 | return -1; | ||
440 | } | ||
441 | break; | ||
442 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 430 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) |
443 | case IPV6_SRCRT_TYPE_2: | 431 | case IPV6_SRCRT_TYPE_2: |
444 | if (accept_source_route < 0) | 432 | if (accept_source_route < 0) |
@@ -576,72 +564,6 @@ void __init ipv6_rthdr_init(void) | |||
576 | printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n"); | 564 | printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n"); |
577 | }; | 565 | }; |
578 | 566 | ||
579 | /* | ||
580 | This function inverts received rthdr. | ||
581 | NOTE: specs allow to make it automatically only if | ||
582 | packet authenticated. | ||
583 | |||
584 | I will not discuss it here (though, I am really pissed off at | ||
585 | this stupid requirement making rthdr idea useless) | ||
586 | |||
587 | Actually, it creates severe problems for us. | ||
588 | Embryonic requests has no associated sockets, | ||
589 | so that user have no control over it and | ||
590 | cannot not only to set reply options, but | ||
591 | even to know, that someone wants to connect | ||
592 | without success. :-( | ||
593 | |||
594 | For now we need to test the engine, so that I created | ||
595 | temporary (or permanent) backdoor. | ||
596 | If listening socket set IPV6_RTHDR to 2, then we invert header. | ||
597 | --ANK (980729) | ||
598 | */ | ||
599 | |||
600 | struct ipv6_txoptions * | ||
601 | ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr) | ||
602 | { | ||
603 | /* Received rthdr: | ||
604 | |||
605 | [ H1 -> H2 -> ... H_prev ] daddr=ME | ||
606 | |||
607 | Inverted result: | ||
608 | [ H_prev -> ... -> H1 ] daddr =sender | ||
609 | |||
610 | Note, that IP output engine will rewrite this rthdr | ||
611 | by rotating it left by one addr. | ||
612 | */ | ||
613 | |||
614 | int n, i; | ||
615 | struct rt0_hdr *rthdr = (struct rt0_hdr*)hdr; | ||
616 | struct rt0_hdr *irthdr; | ||
617 | struct ipv6_txoptions *opt; | ||
618 | int hdrlen = ipv6_optlen(hdr); | ||
619 | |||
620 | if (hdr->segments_left || | ||
621 | hdr->type != IPV6_SRCRT_TYPE_0 || | ||
622 | hdr->hdrlen & 0x01) | ||
623 | return NULL; | ||
624 | |||
625 | n = hdr->hdrlen >> 1; | ||
626 | opt = sock_kmalloc(sk, sizeof(*opt) + hdrlen, GFP_ATOMIC); | ||
627 | if (opt == NULL) | ||
628 | return NULL; | ||
629 | memset(opt, 0, sizeof(*opt)); | ||
630 | opt->tot_len = sizeof(*opt) + hdrlen; | ||
631 | opt->srcrt = (void*)(opt+1); | ||
632 | opt->opt_nflen = hdrlen; | ||
633 | |||
634 | memcpy(opt->srcrt, hdr, sizeof(*hdr)); | ||
635 | irthdr = (struct rt0_hdr*)opt->srcrt; | ||
636 | irthdr->reserved = 0; | ||
637 | opt->srcrt->segments_left = n; | ||
638 | for (i=0; i<n; i++) | ||
639 | memcpy(irthdr->addr+i, rthdr->addr+(n-1-i), 16); | ||
640 | return opt; | ||
641 | } | ||
642 | |||
643 | EXPORT_SYMBOL_GPL(ipv6_invert_rthdr); | ||
644 | |||
645 | /********************************** | 567 | /********************************** |
646 | Hop-by-hop options. | 568 | Hop-by-hop options. |
647 | **********************************/ | 569 | **********************************/ |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 1c3506696cb5..1841714ac419 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -416,11 +416,10 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | |||
416 | if (optname == IPV6_RTHDR && opt && opt->srcrt) { | 416 | if (optname == IPV6_RTHDR && opt && opt->srcrt) { |
417 | struct ipv6_rt_hdr *rthdr = opt->srcrt; | 417 | struct ipv6_rt_hdr *rthdr = opt->srcrt; |
418 | switch (rthdr->type) { | 418 | switch (rthdr->type) { |
419 | case IPV6_SRCRT_TYPE_0: | ||
420 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 419 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) |
421 | case IPV6_SRCRT_TYPE_2: | 420 | case IPV6_SRCRT_TYPE_2: |
422 | #endif | ||
423 | break; | 421 | break; |
422 | #endif | ||
424 | default: | 423 | default: |
425 | goto sticky_done; | 424 | goto sticky_done; |
426 | } | 425 | } |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 193d9d60bb7a..d67fb1ef751e 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -484,17 +484,6 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, | |||
484 | 484 | ||
485 | if (dst == NULL) { | 485 | if (dst == NULL) { |
486 | opt = np->opt; | 486 | opt = np->opt; |
487 | if (opt == NULL && | ||
488 | np->rxopt.bits.osrcrt == 2 && | ||
489 | treq->pktopts) { | ||
490 | struct sk_buff *pktopts = treq->pktopts; | ||
491 | struct inet6_skb_parm *rxopt = IP6CB(pktopts); | ||
492 | if (rxopt->srcrt) | ||
493 | opt = ipv6_invert_rthdr(sk, | ||
494 | (struct ipv6_rt_hdr *)(skb_network_header(pktopts) + | ||
495 | rxopt->srcrt)); | ||
496 | } | ||
497 | |||
498 | if (opt && opt->srcrt) { | 487 | if (opt && opt->srcrt) { |
499 | struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; | 488 | struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; |
500 | ipv6_addr_copy(&final, &fl.fl6_dst); | 489 | ipv6_addr_copy(&final, &fl.fl6_dst); |
@@ -1391,15 +1380,6 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1391 | if (sk_acceptq_is_full(sk)) | 1380 | if (sk_acceptq_is_full(sk)) |
1392 | goto out_overflow; | 1381 | goto out_overflow; |
1393 | 1382 | ||
1394 | if (np->rxopt.bits.osrcrt == 2 && | ||
1395 | opt == NULL && treq->pktopts) { | ||
1396 | struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts); | ||
1397 | if (rxopt->srcrt) | ||
1398 | opt = ipv6_invert_rthdr(sk, | ||
1399 | (struct ipv6_rt_hdr *)(skb_network_header(treq->pktopts) + | ||
1400 | rxopt->srcrt)); | ||
1401 | } | ||
1402 | |||
1403 | if (dst == NULL) { | 1383 | if (dst == NULL) { |
1404 | struct in6_addr *final_p = NULL, final; | 1384 | struct in6_addr *final_p = NULL, final; |
1405 | struct flowi fl; | 1385 | struct flowi fl; |