#include <net/xfrm.h>
#include <net/addrconf.h>
#include <net/snmp.h>
+#include <net/dsfield.h>
#include <asm/uaccess.h>
struct inet_opt *inet = inet_sk(sk);
struct ipv6_pinfo *np = inet6_sk(sk);
struct tcp_opt *tp = tcp_sk(sk);
- struct in6_addr *saddr = NULL;
+ struct in6_addr *saddr = NULL, *final_p = NULL, final;
struct flowi fl;
struct dst_entry *dst;
int addr_type;
if (np->opt && np->opt->srcrt) {
struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
+ ipv6_addr_copy(&final, &fl.fl6_dst);
ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+ final_p = &final;
}
err = ip6_dst_lookup(sk, &dst, &fl);
-
if (err)
goto failure;
+ if (final_p)
+ ipv6_addr_copy(&fl.fl6_dst, final_p);
+
+ if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+ dst_release(dst);
+ goto failure;
+ }
if (saddr == NULL) {
saddr = &fl.fl6_src;
sk->sk_err_soft = -err;
goto out;
}
+
+ if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+ sk->sk_err_soft = -err;
+ goto out;
+ }
+
} else
dst_hold(dst);
struct ipv6_pinfo *np = inet6_sk(sk);
struct sk_buff * skb;
struct ipv6_txoptions *opt = NULL;
+ struct in6_addr * final_p = NULL, final;
struct flowi fl;
int err = -1;
if (opt && opt->srcrt) {
struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
+ ipv6_addr_copy(&final, &fl.fl6_dst);
ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+ final_p = &final;
}
err = ip6_dst_lookup(sk, &dst, &fl);
if (err)
goto done;
+ if (final_p)
+ ipv6_addr_copy(&fl.fl6_dst, final_p);
+ if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+ goto done;
}
skb = tcp_make_synack(sk, dst, req);
* and then put it into the queue to be sent.
*/
- buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr), GFP_ATOMIC);
+ buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + sizeof(struct tcphdr),
+ GFP_ATOMIC);
if (buff == NULL)
return;
- skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr));
+ skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + sizeof(struct tcphdr));
t1 = (struct tcphdr *) skb_push(buff,sizeof(struct tcphdr));
/* sk = NULL, but it is safe for now. RST socket required. */
if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
+
+ if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) {
+ dst_release(buff->dst);
+ return;
+ }
+
ip6_xmit(NULL, buff, &fl, NULL, 0);
TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
TCP_INC_STATS_BH(TCP_MIB_OUTRSTS);
struct flowi fl;
int tot_len = sizeof(struct tcphdr);
- buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr), GFP_ATOMIC);
+ if (ts)
+ tot_len += 3*4;
+
+ buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len,
+ GFP_ATOMIC);
if (buff == NULL)
return;
- skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr));
-
- if (ts)
- tot_len += 3*4;
+ skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len);
t1 = (struct tcphdr *) skb_push(buff,tot_len);
fl.fl_ip_sport = t1->source;
if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
+ if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) {
+ dst_release(buff->dst);
+ return;
+ }
ip6_xmit(NULL, buff, &fl, NULL, 0);
TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
return;
}
if (dst == NULL) {
+ struct in6_addr *final_p = NULL, final;
struct flowi fl;
memset(&fl, 0, sizeof(fl));
ipv6_addr_copy(&fl.fl6_dst, &req->af.v6_req.rmt_addr);
if (opt && opt->srcrt) {
struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
+ ipv6_addr_copy(&final, &fl.fl6_dst);
ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+ final_p = &final;
}
ipv6_addr_copy(&fl.fl6_src, &req->af.v6_req.loc_addr);
fl.oif = sk->sk_bound_dev_if;
if (ip6_dst_lookup(sk, &dst, &fl))
goto out;
+
+ if (final_p)
+ ipv6_addr_copy(&fl.fl6_dst, final_p);
+
+ if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+ goto out;
}
newsk = tcp_create_openreq_child(sk, req, skb);
skb->len - th->doff*4);
TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
TCP_SKB_CB(skb)->when = 0;
- TCP_SKB_CB(skb)->flags = ip6_get_dsfield(skb->nh.ipv6h);
+ TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(skb->nh.ipv6h);
TCP_SKB_CB(skb)->sacked = 0;
sk = __tcp_v6_lookup(&skb->nh.ipv6h->saddr, th->source,
if (dst == NULL) {
struct inet_opt *inet = inet_sk(sk);
+ struct in6_addr *final_p = NULL, final;
struct flowi fl;
memset(&fl, 0, sizeof(fl));
if (np->opt && np->opt->srcrt) {
struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
+ ipv6_addr_copy(&final, &fl.fl6_dst);
ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+ final_p = &final;
}
err = ip6_dst_lookup(sk, &dst, &fl);
-
if (err) {
sk->sk_route_caps = 0;
return err;
}
+ if (final_p)
+ ipv6_addr_copy(&fl.fl6_dst, final_p);
+
+ if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+ sk->sk_err_soft = -err;
+ dst_release(dst);
+ return err;
+ }
ip6_dst_store(sk, dst, NULL);
sk->sk_route_caps = dst->dev->features &
return err;
}
+ if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+ sk->sk_route_caps = 0;
+ dst_release(dst);
+ return err;
+ }
+
ip6_dst_store(sk, dst, NULL);
sk->sk_route_caps = dst->dev->features &
~(NETIF_F_IP_CSUM | NETIF_F_TSO);
*/
tp->snd_ssthresh = 0x7fffffff;
tp->snd_cwnd_clamp = ~0;
- tp->mss_cache = 536;
+ tp->mss_cache_std = tp->mss_cache = 536;
tp->reordering = sysctl_tcp_reordering;
.sysctl_wmem = sysctl_tcp_wmem,
.sysctl_rmem = sysctl_tcp_rmem,
.max_header = MAX_TCP_HEADER,
+ .slab_obj_size = sizeof(struct tcp6_sock),
};
static struct inet6_protocol tcpv6_protocol = {