Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

esp4: split esp_output_udp_encap and introduce esp_output_encap

Co-developed-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>

authored by

Sabrina Dubroca and committed by
Steffen Klassert
eecd227a 25f6802b

+39 -22
+39 -22
net/ipv4/esp4.c
··· 225 225 tail[plen - 1] = proto; 226 226 } 227 227 228 - static int esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp) 228 + static struct ip_esp_hdr *esp_output_udp_encap(struct sk_buff *skb, 229 + int encap_type, 230 + struct esp_info *esp, 231 + __be16 sport, 232 + __be16 dport) 229 233 { 230 - int encap_type; 231 234 struct udphdr *uh; 232 235 __be32 *udpdata32; 233 - __be16 sport, dport; 234 - struct xfrm_encap_tmpl *encap = x->encap; 235 - struct ip_esp_hdr *esph = esp->esph; 236 236 unsigned int len; 237 + 238 + len = skb->len + esp->tailen - skb_transport_offset(skb); 239 + if (len + sizeof(struct iphdr) >= IP_MAX_MTU) 240 + return ERR_PTR(-EMSGSIZE); 241 + 242 + uh = (struct udphdr *)esp->esph; 243 + uh->source = sport; 244 + uh->dest = dport; 245 + uh->len = htons(len); 246 + uh->check = 0; 247 + 248 + *skb_mac_header(skb) = IPPROTO_UDP; 249 + 250 + if (encap_type == UDP_ENCAP_ESPINUDP_NON_IKE) { 251 + udpdata32 = (__be32 *)(uh + 1); 252 + udpdata32[0] = udpdata32[1] = 0; 253 + return (struct ip_esp_hdr *)(udpdata32 + 2); 254 + } 255 + 256 + return (struct ip_esp_hdr *)(uh + 1); 257 + } 258 + 259 + static int esp_output_encap(struct xfrm_state *x, struct sk_buff *skb, 260 + struct esp_info *esp) 261 + { 262 + struct xfrm_encap_tmpl *encap = x->encap; 263 + struct ip_esp_hdr *esph; 264 + __be16 sport, dport; 265 + int encap_type; 237 266 238 267 spin_lock_bh(&x->lock); 239 268 sport = encap->encap_sport; ··· 270 241 encap_type = encap->encap_type; 271 242 spin_unlock_bh(&x->lock); 272 243 273 - len = skb->len + esp->tailen - skb_transport_offset(skb); 274 - if (len + sizeof(struct iphdr) >= IP_MAX_MTU) 275 - return -EMSGSIZE; 276 - 277 - uh = (struct udphdr *)esph; 278 - uh->source = sport; 279 - uh->dest = dport; 280 - uh->len = htons(len); 281 - uh->check = 0; 282 - 283 244 switch (encap_type) { 284 245 default: 285 246 case UDP_ENCAP_ESPINUDP: 286 - esph = (struct ip_esp_hdr *)(uh + 1); 287 - break; 288 247 case UDP_ENCAP_ESPINUDP_NON_IKE: 289 - udpdata32 = (__be32 *)(uh + 1); 290 - udpdata32[0] = udpdata32[1] = 0; 291 - esph = (struct ip_esp_hdr *)(udpdata32 + 2); 248 + esph = esp_output_udp_encap(skb, encap_type, esp, sport, dport); 292 249 break; 293 250 } 294 251 295 - *skb_mac_header(skb) = IPPROTO_UDP; 252 + if (IS_ERR(esph)) 253 + return PTR_ERR(esph); 254 + 296 255 esp->esph = esph; 297 256 298 257 return 0; ··· 298 281 299 282 /* this is non-NULL only with UDP Encapsulation */ 300 283 if (x->encap) { 301 - int err = esp_output_udp_encap(x, skb, esp); 284 + int err = esp_output_encap(x, skb, esp); 302 285 303 286 if (err < 0) 304 287 return err;