diff options
author | David S. Miller <davem@davemloft.net> | 2016-06-30 05:03:36 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-06-30 05:03:36 -0400 |
commit | ee58b57100ca953da7320c285315a95db2f7053d (patch) | |
tree | 77b815a31240adc4d6326346908137fc6c2c3a96 /net/ipv4/esp4.c | |
parent | 6f30e8b022c8e3a722928ddb1a2ae0be852fcc0e (diff) | |
parent | e7bdea7750eb2a64aea4a08fa5c0a31719c8155d (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Several cases of overlapping changes, except the packet scheduler
conflicts which deal with the addition of the free list parameter
to qdisc_enqueue().
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/esp4.c')
-rw-r--r-- | net/ipv4/esp4.c | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 477937465a20..d95631d09248 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
@@ -23,6 +23,11 @@ struct esp_skb_cb { | |||
23 | void *tmp; | 23 | void *tmp; |
24 | }; | 24 | }; |
25 | 25 | ||
26 | struct esp_output_extra { | ||
27 | __be32 seqhi; | ||
28 | u32 esphoff; | ||
29 | }; | ||
30 | |||
26 | #define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0])) | 31 | #define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0])) |
27 | 32 | ||
28 | static u32 esp4_get_mtu(struct xfrm_state *x, int mtu); | 33 | static u32 esp4_get_mtu(struct xfrm_state *x, int mtu); |
@@ -35,11 +40,11 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu); | |||
35 | * | 40 | * |
36 | * TODO: Use spare space in skb for this where possible. | 41 | * TODO: Use spare space in skb for this where possible. |
37 | */ | 42 | */ |
38 | static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags, int seqhilen) | 43 | static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags, int extralen) |
39 | { | 44 | { |
40 | unsigned int len; | 45 | unsigned int len; |
41 | 46 | ||
42 | len = seqhilen; | 47 | len = extralen; |
43 | 48 | ||
44 | len += crypto_aead_ivsize(aead); | 49 | len += crypto_aead_ivsize(aead); |
45 | 50 | ||
@@ -57,15 +62,16 @@ static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags, int seqhilen) | |||
57 | return kmalloc(len, GFP_ATOMIC); | 62 | return kmalloc(len, GFP_ATOMIC); |
58 | } | 63 | } |
59 | 64 | ||
60 | static inline __be32 *esp_tmp_seqhi(void *tmp) | 65 | static inline void *esp_tmp_extra(void *tmp) |
61 | { | 66 | { |
62 | return PTR_ALIGN((__be32 *)tmp, __alignof__(__be32)); | 67 | return PTR_ALIGN(tmp, __alignof__(struct esp_output_extra)); |
63 | } | 68 | } |
64 | static inline u8 *esp_tmp_iv(struct crypto_aead *aead, void *tmp, int seqhilen) | 69 | |
70 | static inline u8 *esp_tmp_iv(struct crypto_aead *aead, void *tmp, int extralen) | ||
65 | { | 71 | { |
66 | return crypto_aead_ivsize(aead) ? | 72 | return crypto_aead_ivsize(aead) ? |
67 | PTR_ALIGN((u8 *)tmp + seqhilen, | 73 | PTR_ALIGN((u8 *)tmp + extralen, |
68 | crypto_aead_alignmask(aead) + 1) : tmp + seqhilen; | 74 | crypto_aead_alignmask(aead) + 1) : tmp + extralen; |
69 | } | 75 | } |
70 | 76 | ||
71 | static inline struct aead_request *esp_tmp_req(struct crypto_aead *aead, u8 *iv) | 77 | static inline struct aead_request *esp_tmp_req(struct crypto_aead *aead, u8 *iv) |
@@ -99,7 +105,7 @@ static void esp_restore_header(struct sk_buff *skb, unsigned int offset) | |||
99 | { | 105 | { |
100 | struct ip_esp_hdr *esph = (void *)(skb->data + offset); | 106 | struct ip_esp_hdr *esph = (void *)(skb->data + offset); |
101 | void *tmp = ESP_SKB_CB(skb)->tmp; | 107 | void *tmp = ESP_SKB_CB(skb)->tmp; |
102 | __be32 *seqhi = esp_tmp_seqhi(tmp); | 108 | __be32 *seqhi = esp_tmp_extra(tmp); |
103 | 109 | ||
104 | esph->seq_no = esph->spi; | 110 | esph->seq_no = esph->spi; |
105 | esph->spi = *seqhi; | 111 | esph->spi = *seqhi; |
@@ -107,7 +113,11 @@ static void esp_restore_header(struct sk_buff *skb, unsigned int offset) | |||
107 | 113 | ||
108 | static void esp_output_restore_header(struct sk_buff *skb) | 114 | static void esp_output_restore_header(struct sk_buff *skb) |
109 | { | 115 | { |
110 | esp_restore_header(skb, skb_transport_offset(skb) - sizeof(__be32)); | 116 | void *tmp = ESP_SKB_CB(skb)->tmp; |
117 | struct esp_output_extra *extra = esp_tmp_extra(tmp); | ||
118 | |||
119 | esp_restore_header(skb, skb_transport_offset(skb) + extra->esphoff - | ||
120 | sizeof(__be32)); | ||
111 | } | 121 | } |
112 | 122 | ||
113 | static void esp_output_done_esn(struct crypto_async_request *base, int err) | 123 | static void esp_output_done_esn(struct crypto_async_request *base, int err) |
@@ -121,6 +131,7 @@ static void esp_output_done_esn(struct crypto_async_request *base, int err) | |||
121 | static int esp_output(struct xfrm_state *x, struct sk_buff *skb) | 131 | static int esp_output(struct xfrm_state *x, struct sk_buff *skb) |
122 | { | 132 | { |
123 | int err; | 133 | int err; |
134 | struct esp_output_extra *extra; | ||
124 | struct ip_esp_hdr *esph; | 135 | struct ip_esp_hdr *esph; |
125 | struct crypto_aead *aead; | 136 | struct crypto_aead *aead; |
126 | struct aead_request *req; | 137 | struct aead_request *req; |
@@ -137,8 +148,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) | |||
137 | int tfclen; | 148 | int tfclen; |
138 | int nfrags; | 149 | int nfrags; |
139 | int assoclen; | 150 | int assoclen; |
140 | int seqhilen; | 151 | int extralen; |
141 | __be32 *seqhi; | ||
142 | __be64 seqno; | 152 | __be64 seqno; |
143 | 153 | ||
144 | /* skb is pure payload to encrypt */ | 154 | /* skb is pure payload to encrypt */ |
@@ -166,21 +176,21 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) | |||
166 | nfrags = err; | 176 | nfrags = err; |
167 | 177 | ||
168 | assoclen = sizeof(*esph); | 178 | assoclen = sizeof(*esph); |
169 | seqhilen = 0; | 179 | extralen = 0; |
170 | 180 | ||
171 | if (x->props.flags & XFRM_STATE_ESN) { | 181 | if (x->props.flags & XFRM_STATE_ESN) { |
172 | seqhilen += sizeof(__be32); | 182 | extralen += sizeof(*extra); |
173 | assoclen += seqhilen; | 183 | assoclen += sizeof(__be32); |
174 | } | 184 | } |
175 | 185 | ||
176 | tmp = esp_alloc_tmp(aead, nfrags, seqhilen); | 186 | tmp = esp_alloc_tmp(aead, nfrags, extralen); |
177 | if (!tmp) { | 187 | if (!tmp) { |
178 | err = -ENOMEM; | 188 | err = -ENOMEM; |
179 | goto error; | 189 | goto error; |
180 | } | 190 | } |
181 | 191 | ||
182 | seqhi = esp_tmp_seqhi(tmp); | 192 | extra = esp_tmp_extra(tmp); |
183 | iv = esp_tmp_iv(aead, tmp, seqhilen); | 193 | iv = esp_tmp_iv(aead, tmp, extralen); |
184 | req = esp_tmp_req(aead, iv); | 194 | req = esp_tmp_req(aead, iv); |
185 | sg = esp_req_sg(aead, req); | 195 | sg = esp_req_sg(aead, req); |
186 | 196 | ||
@@ -247,8 +257,10 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) | |||
247 | * encryption. | 257 | * encryption. |
248 | */ | 258 | */ |
249 | if ((x->props.flags & XFRM_STATE_ESN)) { | 259 | if ((x->props.flags & XFRM_STATE_ESN)) { |
250 | esph = (void *)(skb_transport_header(skb) - sizeof(__be32)); | 260 | extra->esphoff = (unsigned char *)esph - |
251 | *seqhi = esph->spi; | 261 | skb_transport_header(skb); |
262 | esph = (struct ip_esp_hdr *)((unsigned char *)esph - 4); | ||
263 | extra->seqhi = esph->spi; | ||
252 | esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output.hi); | 264 | esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output.hi); |
253 | aead_request_set_callback(req, 0, esp_output_done_esn, skb); | 265 | aead_request_set_callback(req, 0, esp_output_done_esn, skb); |
254 | } | 266 | } |
@@ -445,7 +457,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) | |||
445 | goto out; | 457 | goto out; |
446 | 458 | ||
447 | ESP_SKB_CB(skb)->tmp = tmp; | 459 | ESP_SKB_CB(skb)->tmp = tmp; |
448 | seqhi = esp_tmp_seqhi(tmp); | 460 | seqhi = esp_tmp_extra(tmp); |
449 | iv = esp_tmp_iv(aead, tmp, seqhilen); | 461 | iv = esp_tmp_iv(aead, tmp, seqhilen); |
450 | req = esp_tmp_req(aead, iv); | 462 | req = esp_tmp_req(aead, iv); |
451 | sg = esp_req_sg(aead, req); | 463 | sg = esp_req_sg(aead, req); |