memcpy(top_iph+1, iph+1, top_iph->ihl*4 - sizeof(struct iphdr));
}
- ip_send_check(top_iph);
-
err = 0;
error:
static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
{
int err;
- struct iphdr *top_iph;
struct ip_esp_hdr *esph;
struct crypto_blkcipher *tfm;
struct blkcipher_desc desc;
pskb_put(skb, trailer, clen - skb->len);
skb_push(skb, -skb_network_offset(skb));
- top_iph = ip_hdr(skb);
esph = ip_esp_hdr(skb);
- top_iph->tot_len = htons(skb->len + alen);
*(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb);
*skb_mac_header(skb) = IPPROTO_ESP;
uh = (struct udphdr *)esph;
uh->source = encap->encap_sport;
uh->dest = encap->encap_dport;
- uh->len = htons(skb->len + alen - top_iph->ihl*4);
+ uh->len = htons(skb->len + alen - skb_transport_offset(skb));
uh->check = 0;
switch (encap->encap_type) {
unlock:
spin_unlock_bh(&x->lock);
- ip_send_check(top_iph);
-
error:
return err;
}
static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb)
{
struct ipcomp_data *ipcd = x->data;
- const int ihlen = skb_transport_offset(skb);
- const int plen = skb->len - ihlen;
+ const int plen = skb->len;
int dlen = IPCOMP_SCRATCH_SIZE;
- u8 *start = skb_transport_header(skb);
+ u8 *start = skb->data;
const int cpu = get_cpu();
u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu);
struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu);
memcpy(start + sizeof(struct ip_comp_hdr), scratch, dlen);
put_cpu();
- pskb_trim(skb, ihlen + dlen + sizeof(struct ip_comp_hdr));
+ pskb_trim(skb, dlen + sizeof(struct ip_comp_hdr));
return 0;
out:
int err;
struct ip_comp_hdr *ipch;
struct ipcomp_data *ipcd = x->data;
- int hdr_len = 0;
- struct iphdr *iph = ip_hdr(skb);
- skb_push(skb, -skb_network_offset(skb));
- iph->tot_len = htons(skb->len);
- hdr_len = iph->ihl * 4;
- if ((skb->len - hdr_len) < ipcd->threshold) {
+ if (skb->len < ipcd->threshold) {
/* Don't bother compressing */
goto out_ok;
}
goto out_ok;
err = ipcomp_compress(x, skb);
- iph = ip_hdr(skb);
if (err) {
goto out_ok;
}
/* Install ipcomp header, convert into ipcomp datagram. */
- iph->tot_len = htons(skb->len);
ipch = ip_comp_hdr(skb);
ipch->nexthdr = *skb_mac_header(skb);
ipch->flags = 0;
ipch->cpi = htons((u16 )ntohl(x->id.spi));
*skb_mac_header(skb) = IPPROTO_COMP;
- ip_send_check(iph);
- return 0;
-
out_ok:
- if (x->props.mode == XFRM_MODE_TUNNEL)
- ip_send_check(iph);
+ skb_push(skb, -skb_network_offset(skb));
return 0;
}
/* Add encapsulation header.
*
* The top IP header will be constructed per draft-nikander-esp-beet-mode-06.txt.
- * The following fields in it shall be filled in by x->type->output:
- * tot_len
- * check
*/
static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
{
/* Add encapsulation header.
*
- * The top IP header will be constructed per RFC 2401. The following fields
- * in it shall be filled in by x->type->output:
- * tot_len
- * check
+ * The top IP header will be constructed per RFC 2401.
*/
static int xfrm4_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
{
{
struct dst_entry *dst = skb->dst;
struct xfrm_state *x = dst->xfrm;
+ struct iphdr *iph;
int err;
if (x->props.mode == XFRM_MODE_TUNNEL) {
if (err)
goto error_nolock;
+ iph = ip_hdr(skb);
+ iph->tot_len = htons(skb->len);
+ ip_send_check(iph);
+
IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
err = 0;
static int ipip_output(struct xfrm_state *x, struct sk_buff *skb)
{
- struct iphdr *iph = ip_hdr(skb);
-
skb_push(skb, -skb_network_offset(skb));
- iph->tot_len = htons(skb->len);
- ip_send_check(iph);
-
return 0;
}
static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
{
int err;
- struct ipv6hdr *top_iph;
struct ip_esp_hdr *esph;
struct crypto_blkcipher *tfm;
struct blkcipher_desc desc;
pskb_put(skb, trailer, clen - skb->len);
skb_push(skb, -skb_network_offset(skb));
- top_iph = ipv6_hdr(skb);
esph = ip_esp_hdr(skb);
- top_iph->payload_len = htons(skb->len + alen - sizeof(*top_iph));
*(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb);
*skb_mac_header(skb) = IPPROTO_ESP;
static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb)
{
int err;
- struct ipv6hdr *top_iph;
struct ip_comp_hdr *ipch;
struct ipcomp_data *ipcd = x->data;
int plen, dlen;
u8 *start, *scratch;
struct crypto_comp *tfm;
int cpu;
- int hdr_len;
-
- skb_push(skb, -skb_network_offset(skb));
- hdr_len = skb_transport_offset(skb);
/* check whether datagram len is larger than threshold */
- if ((skb->len - hdr_len) < ipcd->threshold) {
+ if (skb->len < ipcd->threshold) {
goto out_ok;
}
goto out_ok;
/* compression */
- plen = skb->len - hdr_len;
+ plen = skb->len;
dlen = IPCOMP_SCRATCH_SIZE;
- start = skb_transport_header(skb);
+ start = skb->data;
cpu = get_cpu();
scratch = *per_cpu_ptr(ipcomp6_scratches, cpu);
}
memcpy(start + sizeof(struct ip_comp_hdr), scratch, dlen);
put_cpu();
- pskb_trim(skb, hdr_len + dlen + sizeof(struct ip_comp_hdr));
+ pskb_trim(skb, dlen + sizeof(struct ip_comp_hdr));
/* insert ipcomp header and replace datagram */
- top_iph = ipv6_hdr(skb);
-
- top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
-
ipch = ip_comp_hdr(skb);
ipch->nexthdr = *skb_mac_header(skb);
ipch->flags = 0;
*skb_mac_header(skb) = IPPROTO_COMP;
out_ok:
+ skb_push(skb, -skb_network_offset(skb));
+
return 0;
}
skb_push(skb, -skb_network_offset(skb));
iph = ipv6_hdr(skb);
- iph->payload_len = htons(skb->len - sizeof(*iph));
nexthdr = *skb_mac_header(skb);
*skb_mac_header(skb) = IPPROTO_DSTOPTS;
skb_push(skb, -skb_network_offset(skb));
iph = ipv6_hdr(skb);
- iph->payload_len = htons(skb->len - sizeof(*iph));
nexthdr = *skb_mac_header(skb);
*skb_mac_header(skb) = IPPROTO_ROUTING;
/* Add encapsulation header.
*
* The top IP header will be constructed per draft-nikander-esp-beet-mode-06.txt.
- * The following fields in it shall be filled in by x->type->output:
- * payload_len
*/
static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb)
{
/* Add encapsulation header.
*
- * The top IP header will be constructed per RFC 2401. The following fields
- * in it shall be filled in by x->type->output:
- * payload_len
+ * The top IP header will be constructed per RFC 2401.
*/
static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
{
{
struct dst_entry *dst = skb->dst;
struct xfrm_state *x = dst->xfrm;
+ struct ipv6hdr *iph;
int err;
if (x->props.mode == XFRM_MODE_TUNNEL) {
if (err)
goto error_nolock;
+ iph = ipv6_hdr(skb);
+ iph->payload_len = htons(skb->len - sizeof(*iph));
+
IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
err = 0;
static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
{
- struct ipv6hdr *top_iph;
-
skb_push(skb, -skb_network_offset(skb));
- top_iph = ipv6_hdr(skb);
- top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
-
return 0;
}