diff options
Diffstat (limited to 'net/ipv6/xfrm6_mode_tunnel.c')
-rw-r--r-- | net/ipv6/xfrm6_mode_tunnel.c | 36 |
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 | ||
19 | static inline void ipip6_ecn_decapsulate(struct sk_buff *skb) | 19 | static 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 | ||
28 | static inline void ip6ip_ecn_decapsulate(struct sk_buff *skb) | 28 | static 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) | |||
86 | static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) | 86 | static 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 | ||
115 | out: | 119 | out: |