Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * xfrm4_output.c - Common IPsec encapsulation code for IPv4.
  3  * Copyright (c) 2004 Herbert Xu <herbert@gondor.apana.org.au>
  4  *
  5  * This program is free software; you can redistribute it and/or
  6  * modify it under the terms of the GNU General Public License
  7  * as published by the Free Software Foundation; either version
  8  * 2 of the License, or (at your option) any later version.
  9  */
 10 
 11 #include <linux/if_ether.h>
 12 #include <linux/kernel.h>
 13 #include <linux/module.h>
 14 #include <linux/skbuff.h>
 15 #include <linux/netfilter_ipv4.h>
 16 #include <net/dst.h>
 17 #include <net/ip.h>
 18 #include <net/xfrm.h>
 19 #include <net/icmp.h>
 20 
 21 static int xfrm4_tunnel_check_size(struct sk_buff *skb)
 22 {
 23         int mtu, ret = 0;
 24         struct dst_entry *dst;
 25 
 26         if (IPCB(skb)->flags & IPSKB_XFRM_TUNNEL_SIZE)
 27                 goto out;
 28 
 29         if (!(ip_hdr(skb)->frag_off & htons(IP_DF)) || skb->local_df)
 30                 goto out;
 31 
 32         dst = skb_dst(skb);
 33         mtu = dst_mtu(dst);
 34         if (skb->len > mtu) {
 35                 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
 36                 ret = -EMSGSIZE;
 37         }
 38 out:
 39         return ret;
 40 }
 41 
 42 int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb)
 43 {
 44         int err;
 45 
 46         err = xfrm4_tunnel_check_size(skb);
 47         if (err)
 48                 return err;
 49 
 50         XFRM_MODE_SKB_CB(skb)->protocol = ip_hdr(skb)->protocol;
 51 
 52         return xfrm4_extract_header(skb);
 53 }
 54 
 55 int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
 56 {
 57         int err;
 58 
 59         err = xfrm_inner_extract_output(x, skb);
 60         if (err)
 61                 return err;
 62 
 63         memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
 64         IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED;
 65 
 66         skb->protocol = htons(ETH_P_IP);
 67 
 68         return x->outer_mode->output2(x, skb);
 69 }
 70 EXPORT_SYMBOL(xfrm4_prepare_output);
 71 
 72 static int xfrm4_output_finish(struct sk_buff *skb)
 73 {
 74 #ifdef CONFIG_NETFILTER
 75         if (!skb_dst(skb)->xfrm) {
 76                 IPCB(skb)->flags |= IPSKB_REROUTED;
 77                 return dst_output(skb);
 78         }
 79 
 80         IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
 81 #endif
 82 
 83         skb->protocol = htons(ETH_P_IP);
 84         return xfrm_output(skb);
 85 }
 86 
 87 int xfrm4_output(struct sk_buff *skb)
 88 {
 89         return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb,
 90                             NULL, skb_dst(skb)->dev, xfrm4_output_finish,
 91                             !(IPCB(skb)->flags & IPSKB_REROUTED));
 92 }
 93 
  This page was automatically generated by the LXR engine.