mirror of https://gitee.com/openkylin/linux.git
[IPV6]: Do not send RH0 anymore.
Based on <draft-ietf-ipv6-deprecate-rh0-00.txt>. Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c382bb9d32
commit
bb4dbf9e61
|
@ -874,8 +874,7 @@ accept_redirects - BOOLEAN
|
||||||
accept_source_route - INTEGER
|
accept_source_route - INTEGER
|
||||||
Accept source routing (routing extension header).
|
Accept source routing (routing extension header).
|
||||||
|
|
||||||
> 0: Accept routing header.
|
>= 0: Accept only routing header type 2.
|
||||||
= 0: Accept only routing header type 2.
|
|
||||||
< 0: Do not accept routing header.
|
< 0: Do not accept routing header.
|
||||||
|
|
||||||
Default: 0
|
Default: 0
|
||||||
|
|
|
@ -27,8 +27,8 @@ struct in6_ifreq {
|
||||||
int ifr6_ifindex;
|
int ifr6_ifindex;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IPV6_SRCRT_STRICT 0x01 /* this hop must be a neighbor */
|
#define IPV6_SRCRT_STRICT 0x01 /* Deprecated; will be removed */
|
||||||
#define IPV6_SRCRT_TYPE_0 0 /* IPv6 type 0 Routing Header */
|
#define IPV6_SRCRT_TYPE_0 0 /* Deprecated; will be removed */
|
||||||
#define IPV6_SRCRT_TYPE_2 2 /* IPv6 type 2 Routing Header */
|
#define IPV6_SRCRT_TYPE_2 2 /* IPv6 type 2 Routing Header */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -512,10 +512,6 @@ extern int ipv6_ext_hdr(u8 nexthdr);
|
||||||
|
|
||||||
extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type);
|
extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type);
|
||||||
|
|
||||||
extern struct ipv6_txoptions * ipv6_invert_rthdr(struct sock *sk,
|
|
||||||
struct ipv6_rt_hdr *hdr);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* socket options (ipv6_sockglue.c)
|
* socket options (ipv6_sockglue.c)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -253,17 +253,6 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
|
||||||
|
|
||||||
if (dst == NULL) {
|
if (dst == NULL) {
|
||||||
opt = np->opt;
|
opt = np->opt;
|
||||||
if (opt == NULL &&
|
|
||||||
np->rxopt.bits.osrcrt == 2 &&
|
|
||||||
ireq6->pktopts) {
|
|
||||||
struct sk_buff *pktopts = ireq6->pktopts;
|
|
||||||
struct inet6_skb_parm *rxopt = IP6CB(pktopts);
|
|
||||||
|
|
||||||
if (rxopt->srcrt)
|
|
||||||
opt = ipv6_invert_rthdr(sk,
|
|
||||||
(struct ipv6_rt_hdr *)(skb_network_header(pktopts) +
|
|
||||||
rxopt->srcrt));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opt != NULL && opt->srcrt != NULL) {
|
if (opt != NULL && opt->srcrt != NULL) {
|
||||||
const struct rt0_hdr *rt0 = (struct rt0_hdr *)opt->srcrt;
|
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,
|
||||||
if (sk_acceptq_is_full(sk))
|
if (sk_acceptq_is_full(sk))
|
||||||
goto out_overflow;
|
goto out_overflow;
|
||||||
|
|
||||||
if (np->rxopt.bits.osrcrt == 2 && opt == NULL && ireq6->pktopts) {
|
|
||||||
const struct inet6_skb_parm *rxopt = IP6CB(ireq6->pktopts);
|
|
||||||
|
|
||||||
if (rxopt->srcrt)
|
|
||||||
opt = ipv6_invert_rthdr(sk,
|
|
||||||
(struct ipv6_rt_hdr *)(skb_network_header(ireq6->pktopts) +
|
|
||||||
rxopt->srcrt));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dst == NULL) {
|
if (dst == NULL) {
|
||||||
struct in6_addr *final_p = NULL, final;
|
struct in6_addr *final_p = NULL, final;
|
||||||
struct flowi fl;
|
struct flowi fl;
|
||||||
|
|
|
@ -657,11 +657,10 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
|
||||||
rthdr = (struct ipv6_rt_hdr *)CMSG_DATA(cmsg);
|
rthdr = (struct ipv6_rt_hdr *)CMSG_DATA(cmsg);
|
||||||
|
|
||||||
switch (rthdr->type) {
|
switch (rthdr->type) {
|
||||||
case IPV6_SRCRT_TYPE_0:
|
|
||||||
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
|
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
|
||||||
case IPV6_SRCRT_TYPE_2:
|
case IPV6_SRCRT_TYPE_2:
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto exit_f;
|
goto exit_f;
|
||||||
|
|
|
@ -427,18 +427,6 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (hdr->type) {
|
switch (hdr->type) {
|
||||||
case IPV6_SRCRT_TYPE_0:
|
|
||||||
if (accept_source_route <= 0)
|
|
||||||
goto unknown_rh;
|
|
||||||
if (hdr->hdrlen & 0x01) {
|
|
||||||
IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
|
|
||||||
IPSTATS_MIB_INHDRERRORS);
|
|
||||||
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
|
|
||||||
((&hdr->hdrlen) -
|
|
||||||
skb_network_header(skb)));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
|
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
|
||||||
case IPV6_SRCRT_TYPE_2:
|
case IPV6_SRCRT_TYPE_2:
|
||||||
if (accept_source_route < 0)
|
if (accept_source_route < 0)
|
||||||
|
@ -576,72 +564,6 @@ void __init ipv6_rthdr_init(void)
|
||||||
printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n");
|
printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n");
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
This function inverts received rthdr.
|
|
||||||
NOTE: specs allow to make it automatically only if
|
|
||||||
packet authenticated.
|
|
||||||
|
|
||||||
I will not discuss it here (though, I am really pissed off at
|
|
||||||
this stupid requirement making rthdr idea useless)
|
|
||||||
|
|
||||||
Actually, it creates severe problems for us.
|
|
||||||
Embryonic requests has no associated sockets,
|
|
||||||
so that user have no control over it and
|
|
||||||
cannot not only to set reply options, but
|
|
||||||
even to know, that someone wants to connect
|
|
||||||
without success. :-(
|
|
||||||
|
|
||||||
For now we need to test the engine, so that I created
|
|
||||||
temporary (or permanent) backdoor.
|
|
||||||
If listening socket set IPV6_RTHDR to 2, then we invert header.
|
|
||||||
--ANK (980729)
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct ipv6_txoptions *
|
|
||||||
ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr)
|
|
||||||
{
|
|
||||||
/* Received rthdr:
|
|
||||||
|
|
||||||
[ H1 -> H2 -> ... H_prev ] daddr=ME
|
|
||||||
|
|
||||||
Inverted result:
|
|
||||||
[ H_prev -> ... -> H1 ] daddr =sender
|
|
||||||
|
|
||||||
Note, that IP output engine will rewrite this rthdr
|
|
||||||
by rotating it left by one addr.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int n, i;
|
|
||||||
struct rt0_hdr *rthdr = (struct rt0_hdr*)hdr;
|
|
||||||
struct rt0_hdr *irthdr;
|
|
||||||
struct ipv6_txoptions *opt;
|
|
||||||
int hdrlen = ipv6_optlen(hdr);
|
|
||||||
|
|
||||||
if (hdr->segments_left ||
|
|
||||||
hdr->type != IPV6_SRCRT_TYPE_0 ||
|
|
||||||
hdr->hdrlen & 0x01)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
n = hdr->hdrlen >> 1;
|
|
||||||
opt = sock_kmalloc(sk, sizeof(*opt) + hdrlen, GFP_ATOMIC);
|
|
||||||
if (opt == NULL)
|
|
||||||
return NULL;
|
|
||||||
memset(opt, 0, sizeof(*opt));
|
|
||||||
opt->tot_len = sizeof(*opt) + hdrlen;
|
|
||||||
opt->srcrt = (void*)(opt+1);
|
|
||||||
opt->opt_nflen = hdrlen;
|
|
||||||
|
|
||||||
memcpy(opt->srcrt, hdr, sizeof(*hdr));
|
|
||||||
irthdr = (struct rt0_hdr*)opt->srcrt;
|
|
||||||
irthdr->reserved = 0;
|
|
||||||
opt->srcrt->segments_left = n;
|
|
||||||
for (i=0; i<n; i++)
|
|
||||||
memcpy(irthdr->addr+i, rthdr->addr+(n-1-i), 16);
|
|
||||||
return opt;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(ipv6_invert_rthdr);
|
|
||||||
|
|
||||||
/**********************************
|
/**********************************
|
||||||
Hop-by-hop options.
|
Hop-by-hop options.
|
||||||
**********************************/
|
**********************************/
|
||||||
|
|
|
@ -416,11 +416,10 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
|
||||||
if (optname == IPV6_RTHDR && opt && opt->srcrt) {
|
if (optname == IPV6_RTHDR && opt && opt->srcrt) {
|
||||||
struct ipv6_rt_hdr *rthdr = opt->srcrt;
|
struct ipv6_rt_hdr *rthdr = opt->srcrt;
|
||||||
switch (rthdr->type) {
|
switch (rthdr->type) {
|
||||||
case IPV6_SRCRT_TYPE_0:
|
|
||||||
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
|
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
|
||||||
case IPV6_SRCRT_TYPE_2:
|
case IPV6_SRCRT_TYPE_2:
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
goto sticky_done;
|
goto sticky_done;
|
||||||
}
|
}
|
||||||
|
|
|
@ -484,17 +484,6 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
|
||||||
|
|
||||||
if (dst == NULL) {
|
if (dst == NULL) {
|
||||||
opt = np->opt;
|
opt = np->opt;
|
||||||
if (opt == NULL &&
|
|
||||||
np->rxopt.bits.osrcrt == 2 &&
|
|
||||||
treq->pktopts) {
|
|
||||||
struct sk_buff *pktopts = treq->pktopts;
|
|
||||||
struct inet6_skb_parm *rxopt = IP6CB(pktopts);
|
|
||||||
if (rxopt->srcrt)
|
|
||||||
opt = ipv6_invert_rthdr(sk,
|
|
||||||
(struct ipv6_rt_hdr *)(skb_network_header(pktopts) +
|
|
||||||
rxopt->srcrt));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opt && opt->srcrt) {
|
if (opt && opt->srcrt) {
|
||||||
struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
|
struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
|
||||||
ipv6_addr_copy(&final, &fl.fl6_dst);
|
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,
|
||||||
if (sk_acceptq_is_full(sk))
|
if (sk_acceptq_is_full(sk))
|
||||||
goto out_overflow;
|
goto out_overflow;
|
||||||
|
|
||||||
if (np->rxopt.bits.osrcrt == 2 &&
|
|
||||||
opt == NULL && treq->pktopts) {
|
|
||||||
struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts);
|
|
||||||
if (rxopt->srcrt)
|
|
||||||
opt = ipv6_invert_rthdr(sk,
|
|
||||||
(struct ipv6_rt_hdr *)(skb_network_header(treq->pktopts) +
|
|
||||||
rxopt->srcrt));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dst == NULL) {
|
if (dst == NULL) {
|
||||||
struct in6_addr *final_p = NULL, final;
|
struct in6_addr *final_p = NULL, final;
|
||||||
struct flowi fl;
|
struct flowi fl;
|
||||||
|
|
Loading…
Reference in New Issue