aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/networking/ip-sysctl.txt3
-rw-r--r--include/linux/ipv6.h4
-rw-r--r--include/net/ipv6.h4
-rw-r--r--net/dccp/ipv6.c20
-rw-r--r--net/ipv6/datagram.c3
-rw-r--r--net/ipv6/exthdrs.c78
-rw-r--r--net/ipv6/ipv6_sockglue.c3
-rw-r--r--net/ipv6/tcp_ipv6.c20
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
874accept_source_route - INTEGER 874accept_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
513extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type); 513extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type);
514 514
515extern 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
600struct ipv6_txoptions *
601ipv6_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
643EXPORT_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;