diff options
-rw-r--r-- | Documentation/networking/ip-sysctl.txt | 3 | ||||
-rw-r--r-- | include/linux/ipv6.h | 4 | ||||
-rw-r--r-- | include/net/ipv6.h | 4 | ||||
-rw-r--r-- | net/dccp/ipv6.c | 20 | ||||
-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 |
8 files changed, 5 insertions, 130 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index af6a63ab9026..09c184e41cf8 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
@@ -874,8 +874,7 @@ accept_redirects - BOOLEAN | |||
874 | accept_source_route - INTEGER | 874 | accept_source_route - INTEGER |
875 | Accept source routing (routing extension header). | 875 | Accept source routing (routing extension header). |
876 | 876 | ||
877 | > 0: Accept routing header. | 877 | >= 0: Accept only routing header type 2. |
878 | = 0: Accept only routing header type 2. | ||
879 | < 0: Do not accept routing header. | 878 | < 0: Do not accept routing header. |
880 | 879 | ||
881 | Default: 0 | 880 | Default: 0 |
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 213b63be3c8f..cb3118cf277c 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h | |||
@@ -27,8 +27,8 @@ struct in6_ifreq { | |||
27 | int ifr6_ifindex; | 27 | int ifr6_ifindex; |
28 | }; | 28 | }; |
29 | 29 | ||
30 | #define IPV6_SRCRT_STRICT 0x01 /* this hop must be a neighbor */ | 30 | #define IPV6_SRCRT_STRICT 0x01 /* Deprecated; will be removed */ |
31 | #define IPV6_SRCRT_TYPE_0 0 /* IPv6 type 0 Routing Header */ | 31 | #define IPV6_SRCRT_TYPE_0 0 /* Deprecated; will be removed */ |
32 | #define IPV6_SRCRT_TYPE_2 2 /* IPv6 type 2 Routing Header */ | 32 | #define IPV6_SRCRT_TYPE_2 2 /* IPv6 type 2 Routing Header */ |
33 | 33 | ||
34 | /* | 34 | /* |
diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 78a0d06d98d5..46b9dce82f6e 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h | |||
@@ -512,10 +512,6 @@ extern int ipv6_ext_hdr(u8 nexthdr); | |||
512 | 512 | ||
513 | extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type); | 513 | extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type); |
514 | 514 | ||
515 | extern struct ipv6_txoptions * ipv6_invert_rthdr(struct sock *sk, | ||
516 | struct ipv6_rt_hdr *hdr); | ||
517 | |||
518 | |||
519 | /* | 515 | /* |
520 | * socket options (ipv6_sockglue.c) | 516 | * socket options (ipv6_sockglue.c) |
521 | */ | 517 | */ |
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 31737cdf156a..b158c661867b 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -253,17 +253,6 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req, | |||
253 | 253 | ||
254 | if (dst == NULL) { | 254 | if (dst == NULL) { |
255 | opt = np->opt; | 255 | opt = np->opt; |
256 | if (opt == NULL && | ||
257 | np->rxopt.bits.osrcrt == 2 && | ||
258 | ireq6->pktopts) { | ||
259 | struct sk_buff *pktopts = ireq6->pktopts; | ||
260 | struct inet6_skb_parm *rxopt = IP6CB(pktopts); | ||
261 | |||
262 | if (rxopt->srcrt) | ||
263 | opt = ipv6_invert_rthdr(sk, | ||
264 | (struct ipv6_rt_hdr *)(skb_network_header(pktopts) + | ||
265 | rxopt->srcrt)); | ||
266 | } | ||
267 | 256 | ||
268 | if (opt != NULL && opt->srcrt != NULL) { | 257 | if (opt != NULL && opt->srcrt != NULL) { |
269 | const struct rt0_hdr *rt0 = (struct rt0_hdr *)opt->srcrt; | 258 | const struct rt0_hdr *rt0 = (struct rt0_hdr *)opt->srcrt; |
@@ -570,15 +559,6 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, | |||
570 | if (sk_acceptq_is_full(sk)) | 559 | if (sk_acceptq_is_full(sk)) |
571 | goto out_overflow; | 560 | goto out_overflow; |
572 | 561 | ||
573 | if (np->rxopt.bits.osrcrt == 2 && opt == NULL && ireq6->pktopts) { | ||
574 | const struct inet6_skb_parm *rxopt = IP6CB(ireq6->pktopts); | ||
575 | |||
576 | if (rxopt->srcrt) | ||
577 | opt = ipv6_invert_rthdr(sk, | ||
578 | (struct ipv6_rt_hdr *)(skb_network_header(ireq6->pktopts) + | ||
579 | rxopt->srcrt)); | ||
580 | } | ||
581 | |||
582 | if (dst == NULL) { | 562 | if (dst == NULL) { |
583 | struct in6_addr *final_p = NULL, final; | 563 | struct in6_addr *final_p = NULL, final; |
584 | struct flowi fl; | 564 | struct flowi fl; |
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; |