- encap = x->encap;
-
- iph = skb->nh.iph;
- if (x->props.mode) {
- top_iph = (struct iphdr*)skb_push(skb, x->props.header_len);
- esph = (struct ip_esp_hdr*)(top_iph+1);
- if (encap && encap->encap_type) {
- switch (encap->encap_type) {
- case UDP_ENCAP_ESPINUDP:
- uh = (struct udphdr*) esph;
- esph = (struct ip_esp_hdr*)(uh+1);
- top_iph->protocol = IPPROTO_UDP;
- break;
- case UDP_ENCAP_ESPINUDP_NON_IKE:
- uh = (struct udphdr*) esph;
- udpdata32 = (u32*)(uh+1);
- udpdata32[0] = udpdata32[1] = 0;
- esph = (struct ip_esp_hdr*)(udpdata32+2);
- alen += 2;
- top_iph->protocol = IPPROTO_UDP;
- break;
- default:
- printk(KERN_INFO
- "esp_output(): Unhandled encap: %u\n",
- encap->encap_type);
- top_iph->protocol = IPPROTO_ESP;
- break;
- }
- } else
- top_iph->protocol = IPPROTO_ESP;
- *(u8*)(trailer->tail - 1) = IPPROTO_IPIP;
- top_iph->ihl = 5;
- top_iph->version = 4;
- top_iph->tos = iph->tos; /* DS disclosed */
- if (x->props.flags & XFRM_STATE_NOECN)
- IP_ECN_clear(top_iph);
- top_iph->tot_len = htons(skb->len + alen);
- top_iph->frag_off = iph->frag_off&htons(IP_DF);
- if (!(top_iph->frag_off))
- ip_select_ident(top_iph, dst, 0);
- top_iph->ttl = iph->ttl; /* TTL disclosed */
- top_iph->check = 0;
- top_iph->saddr = x->props.saddr.a4;
- top_iph->daddr = x->id.daddr.a4;
- memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
- } else {
- esph = (struct ip_esp_hdr*)skb_push(skb, x->props.header_len);
- top_iph = (struct iphdr*)skb_push(skb, iph->ihl*4);
- memcpy(top_iph, &tmp_iph, iph->ihl*4);
- if (encap && encap->encap_type) {
- switch (encap->encap_type) {
- case UDP_ENCAP_ESPINUDP:
- uh = (struct udphdr*) esph;
- esph = (struct ip_esp_hdr*)(uh+1);
- top_iph->protocol = IPPROTO_UDP;
- break;
- case UDP_ENCAP_ESPINUDP_NON_IKE:
- uh = (struct udphdr*) esph;
- udpdata32 = (u32*)(uh+1);
- udpdata32[0] = udpdata32[1] = 0;
- esph = (struct ip_esp_hdr*)(udpdata32+2);
- alen += 2;
- top_iph->protocol = IPPROTO_UDP;
- break;
- default:
- printk(KERN_INFO
- "esp_output(): Unhandled encap: %u\n",
- encap->encap_type);
- top_iph->protocol = IPPROTO_ESP;
- break;
- }
- } else
- top_iph->protocol = IPPROTO_ESP;
- iph = &tmp_iph.iph;
- top_iph->tot_len = htons(skb->len + alen);
- top_iph->check = 0;
- top_iph->frag_off = iph->frag_off;
- *(u8*)(trailer->tail - 1) = iph->protocol;
- }