aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/esp4.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/esp4.c')
-rw-r--r--net/ipv4/esp4.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 10e809b296ec..fb065a8937ea 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -226,7 +226,7 @@ static void esp_output_fill_trailer(u8 *tail, int tfclen, int plen, __u8 proto)
226 tail[plen - 1] = proto; 226 tail[plen - 1] = proto;
227} 227}
228 228
229static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp) 229static int esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp)
230{ 230{
231 int encap_type; 231 int encap_type;
232 struct udphdr *uh; 232 struct udphdr *uh;
@@ -234,6 +234,7 @@ static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, stru
234 __be16 sport, dport; 234 __be16 sport, dport;
235 struct xfrm_encap_tmpl *encap = x->encap; 235 struct xfrm_encap_tmpl *encap = x->encap;
236 struct ip_esp_hdr *esph = esp->esph; 236 struct ip_esp_hdr *esph = esp->esph;
237 unsigned int len;
237 238
238 spin_lock_bh(&x->lock); 239 spin_lock_bh(&x->lock);
239 sport = encap->encap_sport; 240 sport = encap->encap_sport;
@@ -241,11 +242,14 @@ static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, stru
241 encap_type = encap->encap_type; 242 encap_type = encap->encap_type;
242 spin_unlock_bh(&x->lock); 243 spin_unlock_bh(&x->lock);
243 244
245 len = skb->len + esp->tailen - skb_transport_offset(skb);
246 if (len + sizeof(struct iphdr) >= IP_MAX_MTU)
247 return -EMSGSIZE;
248
244 uh = (struct udphdr *)esph; 249 uh = (struct udphdr *)esph;
245 uh->source = sport; 250 uh->source = sport;
246 uh->dest = dport; 251 uh->dest = dport;
247 uh->len = htons(skb->len + esp->tailen 252 uh->len = htons(len);
248 - skb_transport_offset(skb));
249 uh->check = 0; 253 uh->check = 0;
250 254
251 switch (encap_type) { 255 switch (encap_type) {
@@ -262,6 +266,8 @@ static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, stru
262 266
263 *skb_mac_header(skb) = IPPROTO_UDP; 267 *skb_mac_header(skb) = IPPROTO_UDP;
264 esp->esph = esph; 268 esp->esph = esph;
269
270 return 0;
265} 271}
266 272
267int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp) 273int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp)
@@ -275,8 +281,12 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
275 int tailen = esp->tailen; 281 int tailen = esp->tailen;
276 282
277 /* this is non-NULL only with UDP Encapsulation */ 283 /* this is non-NULL only with UDP Encapsulation */
278 if (x->encap) 284 if (x->encap) {
279 esp_output_udp_encap(x, skb, esp); 285 int err = esp_output_udp_encap(x, skb, esp);
286
287 if (err < 0)
288 return err;
289 }
280 290
281 if (!skb_cloned(skb)) { 291 if (!skb_cloned(skb)) {
282 if (tailen <= skb_tailroom(skb)) { 292 if (tailen <= skb_tailroom(skb)) {