aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/xfrm6_mode_tunnel.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/xfrm6_mode_tunnel.c')
-rw-r--r--net/ipv6/xfrm6_mode_tunnel.c31
1 files changed, 10 insertions, 21 deletions
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index 9a43ea722481..d45ce5d44197 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -38,33 +38,22 @@ static inline void ip6ip_ecn_decapsulate(struct sk_buff *skb)
38static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) 38static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
39{ 39{
40 struct dst_entry *dst = skb->dst; 40 struct dst_entry *dst = skb->dst;
41 struct xfrm_dst *xdst = (struct xfrm_dst*)dst; 41 struct ipv6hdr *top_iph;
42 struct ipv6hdr *iph, *top_iph;
43 int dsfield; 42 int dsfield;
44 43
45 iph = ipv6_hdr(skb);
46
47 skb_set_network_header(skb, -x->props.header_len); 44 skb_set_network_header(skb, -x->props.header_len);
48 skb->mac_header = skb->network_header + 45 skb->mac_header = skb->network_header +
49 offsetof(struct ipv6hdr, nexthdr); 46 offsetof(struct ipv6hdr, nexthdr);
50 skb->transport_header = skb->network_header + sizeof(*iph); 47 skb->transport_header = skb->network_header + sizeof(*top_iph);
51 top_iph = ipv6_hdr(skb); 48 top_iph = ipv6_hdr(skb);
52 49
53 top_iph->version = 6; 50 top_iph->version = 6;
54 if (xdst->route->ops->family == AF_INET6) { 51
55 top_iph->priority = iph->priority; 52 memcpy(top_iph->flow_lbl, XFRM_MODE_SKB_CB(skb)->flow_lbl,
56 top_iph->flow_lbl[0] = iph->flow_lbl[0]; 53 sizeof(top_iph->flow_lbl));
57 top_iph->flow_lbl[1] = iph->flow_lbl[1]; 54 top_iph->nexthdr = x->inner_mode->afinfo->proto;
58 top_iph->flow_lbl[2] = iph->flow_lbl[2]; 55
59 top_iph->nexthdr = IPPROTO_IPV6; 56 dsfield = XFRM_MODE_SKB_CB(skb)->tos;
60 } else {
61 top_iph->priority = 0;
62 top_iph->flow_lbl[0] = 0;
63 top_iph->flow_lbl[1] = 0;
64 top_iph->flow_lbl[2] = 0;
65 top_iph->nexthdr = IPPROTO_IPIP;
66 }
67 dsfield = ipv6_get_dsfield(top_iph);
68 dsfield = INET_ECN_encapsulate(dsfield, dsfield); 57 dsfield = INET_ECN_encapsulate(dsfield, dsfield);
69 if (x->props.flags & XFRM_STATE_NOECN) 58 if (x->props.flags & XFRM_STATE_NOECN)
70 dsfield &= ~INET_ECN_MASK; 59 dsfield &= ~INET_ECN_MASK;
@@ -72,7 +61,6 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
72 top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT); 61 top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT);
73 ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr); 62 ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
74 ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr); 63 ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
75 skb->protocol = htons(ETH_P_IPV6);
76 return 0; 64 return 0;
77} 65}
78 66
@@ -116,7 +104,8 @@ out:
116 104
117static struct xfrm_mode xfrm6_tunnel_mode = { 105static struct xfrm_mode xfrm6_tunnel_mode = {
118 .input = xfrm6_tunnel_input, 106 .input = xfrm6_tunnel_input,
119 .output = xfrm6_tunnel_output, 107 .output2 = xfrm6_tunnel_output,
108 .output = xfrm6_prepare_output,
120 .owner = THIS_MODULE, 109 .owner = THIS_MODULE,
121 .encap = XFRM_MODE_TUNNEL, 110 .encap = XFRM_MODE_TUNNEL,
122 .flags = XFRM_MODE_FLAG_TUNNEL, 111 .flags = XFRM_MODE_FLAG_TUNNEL,