aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/xfrm.h1
-rw-r--r--net/ipv4/xfrm4_input.c13
-rw-r--r--net/ipv4/xfrm4_output.c2
-rw-r--r--net/ipv4/xfrm4_state.c1
-rw-r--r--net/ipv6/xfrm6_input.c4
-rw-r--r--net/ipv6/xfrm6_output.c3
-rw-r--r--net/ipv6/xfrm6_state.c2
-rw-r--r--net/xfrm/xfrm_input.c5
8 files changed, 16 insertions, 15 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 311bbd113aa7..cf85dc9dc420 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -534,7 +534,6 @@ struct xfrm_spi_skb_cb {
534 struct inet6_skb_parm h6; 534 struct inet6_skb_parm h6;
535 } header; 535 } header;
536 536
537 unsigned int nhoff;
538 unsigned int daddroff; 537 unsigned int daddroff;
539}; 538};
540 539
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index e374903dacdf..662d1e86cfbf 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -21,7 +21,6 @@ int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb)
21 return xfrm4_extract_header(skb); 21 return xfrm4_extract_header(skb);
22} 22}
23 23
24#ifdef CONFIG_NETFILTER
25static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb) 24static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb)
26{ 25{
27 if (skb->dst == NULL) { 26 if (skb->dst == NULL) {
@@ -36,12 +35,10 @@ drop:
36 kfree_skb(skb); 35 kfree_skb(skb);
37 return NET_RX_DROP; 36 return NET_RX_DROP;
38} 37}
39#endif
40 38
41int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi, 39int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
42 int encap_type) 40 int encap_type)
43{ 41{
44 XFRM_SPI_SKB_CB(skb)->nhoff = offsetof(struct iphdr, protocol);
45 XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr); 42 XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
46 return xfrm_input(skb, nexthdr, spi, encap_type); 43 return xfrm_input(skb, nexthdr, spi, encap_type);
47} 44}
@@ -49,16 +46,20 @@ EXPORT_SYMBOL(xfrm4_rcv_encap);
49 46
50int xfrm4_transport_finish(struct sk_buff *skb, int async) 47int xfrm4_transport_finish(struct sk_buff *skb, int async)
51{ 48{
49 struct iphdr *iph = ip_hdr(skb);
50
51 iph->protocol = XFRM_MODE_SKB_CB(skb)->protocol;
52
52#ifdef CONFIG_NETFILTER 53#ifdef CONFIG_NETFILTER
53 __skb_push(skb, skb->data - skb_network_header(skb)); 54 __skb_push(skb, skb->data - skb_network_header(skb));
54 ip_hdr(skb)->tot_len = htons(skb->len); 55 iph->tot_len = htons(skb->len);
55 ip_send_check(ip_hdr(skb)); 56 ip_send_check(iph);
56 57
57 NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL, 58 NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL,
58 xfrm4_rcv_encap_finish); 59 xfrm4_rcv_encap_finish);
59 return 0; 60 return 0;
60#else 61#else
61 return -ip_hdr(skb)->protocol; 62 return -iph->protocol;
62#endif 63#endif
63} 64}
64 65
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index 2fb4efa3ff2c..1900200d3c0f 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -47,6 +47,8 @@ int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb)
47 if (err) 47 if (err)
48 return err; 48 return err;
49 49
50 XFRM_MODE_SKB_CB(skb)->protocol = ip_hdr(skb)->protocol;
51
50 return xfrm4_extract_header(skb); 52 return xfrm4_extract_header(skb);
51} 53}
52 54
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
index 3b067e8b7bfe..d837784a2199 100644
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -56,7 +56,6 @@ int xfrm4_extract_header(struct sk_buff *skb)
56 XFRM_MODE_SKB_CB(skb)->frag_off = iph->frag_off; 56 XFRM_MODE_SKB_CB(skb)->frag_off = iph->frag_off;
57 XFRM_MODE_SKB_CB(skb)->tos = iph->tos; 57 XFRM_MODE_SKB_CB(skb)->tos = iph->tos;
58 XFRM_MODE_SKB_CB(skb)->ttl = iph->ttl; 58 XFRM_MODE_SKB_CB(skb)->ttl = iph->ttl;
59 XFRM_MODE_SKB_CB(skb)->protocol = iph->protocol;
60 memset(XFRM_MODE_SKB_CB(skb)->flow_lbl, 0, 59 memset(XFRM_MODE_SKB_CB(skb)->flow_lbl, 0,
61 sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl)); 60 sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl));
62 61
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 3b9eedf5b24a..5c006c845943 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -23,7 +23,6 @@ int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb)
23 23
24int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi) 24int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
25{ 25{
26 XFRM_SPI_SKB_CB(skb)->nhoff = IP6CB(skb)->nhoff;
27 XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr); 26 XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr);
28 return xfrm_input(skb, nexthdr, spi, 0); 27 return xfrm_input(skb, nexthdr, spi, 0);
29} 28}
@@ -31,6 +30,9 @@ EXPORT_SYMBOL(xfrm6_rcv_spi);
31 30
32int xfrm6_transport_finish(struct sk_buff *skb, int async) 31int xfrm6_transport_finish(struct sk_buff *skb, int async)
33{ 32{
33 skb_network_header(skb)[IP6CB(skb)->nhoff] =
34 XFRM_MODE_SKB_CB(skb)->protocol;
35
34#ifdef CONFIG_NETFILTER 36#ifdef CONFIG_NETFILTER
35 ipv6_hdr(skb)->payload_len = htons(skb->len); 37 ipv6_hdr(skb)->payload_len = htons(skb->len);
36 __skb_push(skb, skb->data - skb_network_header(skb)); 38 __skb_push(skb, skb->data - skb_network_header(skb));
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index a0a924991c4f..318669a9cb48 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -53,7 +53,8 @@ int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb)
53 if (err) 53 if (err)
54 return err; 54 return err;
55 55
56 IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); 56 XFRM_MODE_SKB_CB(skb)->protocol = ipv6_hdr(skb)->nexthdr;
57
57 return xfrm6_extract_header(skb); 58 return xfrm6_extract_header(skb);
58} 59}
59 60
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index 00360b514e99..df7e98d914fa 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -178,8 +178,6 @@ int xfrm6_extract_header(struct sk_buff *skb)
178 XFRM_MODE_SKB_CB(skb)->frag_off = htons(IP_DF); 178 XFRM_MODE_SKB_CB(skb)->frag_off = htons(IP_DF);
179 XFRM_MODE_SKB_CB(skb)->tos = ipv6_get_dsfield(iph); 179 XFRM_MODE_SKB_CB(skb)->tos = ipv6_get_dsfield(iph);
180 XFRM_MODE_SKB_CB(skb)->ttl = iph->hop_limit; 180 XFRM_MODE_SKB_CB(skb)->ttl = iph->hop_limit;
181 XFRM_MODE_SKB_CB(skb)->protocol =
182 skb_network_header(skb)[IP6CB(skb)->nhoff];
183 memcpy(XFRM_MODE_SKB_CB(skb)->flow_lbl, iph->flow_lbl, 181 memcpy(XFRM_MODE_SKB_CB(skb)->flow_lbl, iph->flow_lbl,
184 sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl)); 182 sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl));
185 183
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 5cad522e8ef6..cce9d4586045 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -102,7 +102,6 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
102 __be32 seq; 102 __be32 seq;
103 struct xfrm_state *x; 103 struct xfrm_state *x;
104 int decaps = 0; 104 int decaps = 0;
105 unsigned int nhoff = XFRM_SPI_SKB_CB(skb)->nhoff;
106 unsigned int daddroff = XFRM_SPI_SKB_CB(skb)->daddroff; 105 unsigned int daddroff = XFRM_SPI_SKB_CB(skb)->daddroff;
107 106
108 /* Allocate new secpath or COW existing one. */ 107 /* Allocate new secpath or COW existing one. */
@@ -157,8 +156,6 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
157 goto drop_unlock; 156 goto drop_unlock;
158 } 157 }
159 158
160 skb_network_header(skb)[nhoff] = nexthdr;
161
162 /* only the first xfrm gets the encap type */ 159 /* only the first xfrm gets the encap type */
163 encap_type = 0; 160 encap_type = 0;
164 161
@@ -170,6 +167,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
170 167
171 spin_unlock(&x->lock); 168 spin_unlock(&x->lock);
172 169
170 XFRM_MODE_SKB_CB(skb)->protocol = nexthdr;
171
173 if (x->inner_mode->input(x, skb)) 172 if (x->inner_mode->input(x, skb))
174 goto drop; 173 goto drop;
175 174