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.c36
1 files changed, 20 insertions, 16 deletions
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index 0bc866c0d83c..a6c0cdf46ad6 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -18,8 +18,8 @@
18 18
19static inline void ipip6_ecn_decapsulate(struct sk_buff *skb) 19static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
20{ 20{
21 struct ipv6hdr *outer_iph = skb->nh.ipv6h; 21 struct ipv6hdr *outer_iph = ipv6_hdr(skb);
22 struct ipv6hdr *inner_iph = skb->h.ipv6h; 22 struct ipv6hdr *inner_iph = ipipv6_hdr(skb);
23 23
24 if (INET_ECN_is_ce(ipv6_get_dsfield(outer_iph))) 24 if (INET_ECN_is_ce(ipv6_get_dsfield(outer_iph)))
25 IP6_ECN_set_ce(inner_iph); 25 IP6_ECN_set_ce(inner_iph);
@@ -27,8 +27,8 @@ static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
27 27
28static inline void ip6ip_ecn_decapsulate(struct sk_buff *skb) 28static inline void ip6ip_ecn_decapsulate(struct sk_buff *skb)
29{ 29{
30 if (INET_ECN_is_ce(ipv6_get_dsfield(skb->nh.ipv6h))) 30 if (INET_ECN_is_ce(ipv6_get_dsfield(ipv6_hdr(skb))))
31 IP_ECN_set_ce(skb->h.ipiph); 31 IP_ECN_set_ce(ipip_hdr(skb));
32} 32}
33 33
34/* Add encapsulation header. 34/* Add encapsulation header.
@@ -51,12 +51,12 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
51 int dsfield; 51 int dsfield;
52 52
53 skb_push(skb, x->props.header_len); 53 skb_push(skb, x->props.header_len);
54 iph = skb->nh.ipv6h; 54 iph = ipv6_hdr(skb);
55 55
56 skb->nh.raw = skb->data; 56 skb_reset_network_header(skb);
57 top_iph = skb->nh.ipv6h; 57 top_iph = ipv6_hdr(skb);
58 skb->nh.raw = &top_iph->nexthdr; 58 skb->transport_header = skb->network_header + sizeof(struct ipv6hdr);
59 skb->h.ipv6h = top_iph + 1; 59 skb->network_header += offsetof(struct ipv6hdr, nexthdr);
60 60
61 top_iph->version = 6; 61 top_iph->version = 6;
62 if (xdst->route->ops->family == AF_INET6) { 62 if (xdst->route->ops->family == AF_INET6) {
@@ -86,9 +86,11 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
86static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) 86static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
87{ 87{
88 int err = -EINVAL; 88 int err = -EINVAL;
89 const unsigned char *old_mac;
90 const unsigned char *nh = skb_network_header(skb);
89 91
90 if (skb->nh.raw[IP6CB(skb)->nhoff] != IPPROTO_IPV6 92 if (nh[IP6CB(skb)->nhoff] != IPPROTO_IPV6 &&
91 && skb->nh.raw[IP6CB(skb)->nhoff] != IPPROTO_IPIP) 93 nh[IP6CB(skb)->nhoff] != IPPROTO_IPIP)
92 goto out; 94 goto out;
93 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) 95 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
94 goto out; 96 goto out;
@@ -97,9 +99,10 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
97 (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) 99 (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
98 goto out; 100 goto out;
99 101
100 if (skb->nh.raw[IP6CB(skb)->nhoff] == IPPROTO_IPV6) { 102 nh = skb_network_header(skb);
103 if (nh[IP6CB(skb)->nhoff] == IPPROTO_IPV6) {
101 if (x->props.flags & XFRM_STATE_DECAP_DSCP) 104 if (x->props.flags & XFRM_STATE_DECAP_DSCP)
102 ipv6_copy_dscp(skb->nh.ipv6h, skb->h.ipv6h); 105 ipv6_copy_dscp(ipv6_hdr(skb), ipipv6_hdr(skb));
103 if (!(x->props.flags & XFRM_STATE_NOECN)) 106 if (!(x->props.flags & XFRM_STATE_NOECN))
104 ipip6_ecn_decapsulate(skb); 107 ipip6_ecn_decapsulate(skb);
105 } else { 108 } else {
@@ -107,9 +110,10 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
107 ip6ip_ecn_decapsulate(skb); 110 ip6ip_ecn_decapsulate(skb);
108 skb->protocol = htons(ETH_P_IP); 111 skb->protocol = htons(ETH_P_IP);
109 } 112 }
110 skb->mac.raw = memmove(skb->data - skb->mac_len, 113 old_mac = skb_mac_header(skb);
111 skb->mac.raw, skb->mac_len); 114 skb_set_mac_header(skb, -skb->mac_len);
112 skb->nh.raw = skb->data; 115 memmove(skb_mac_header(skb), old_mac, skb->mac_len);
116 skb_reset_network_header(skb);
113 err = 0; 117 err = 0;
114 118
115out: 119out: