root/net/ipv4/xfrm4_input.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. xfrm4_extract_input
  2. xfrm4_rcv_encap_finish2
  3. xfrm4_rcv_encap_finish
  4. xfrm4_transport_finish
  5. xfrm4_udp_encap_rcv
  6. xfrm4_rcv

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * xfrm4_input.c
   4  *
   5  * Changes:
   6  *      YOSHIFUJI Hideaki @USAGI
   7  *              Split up af-specific portion
   8  *      Derek Atkins <derek@ihtfp.com>
   9  *              Add Encapsulation support
  10  *
  11  */
  12 
  13 #include <linux/slab.h>
  14 #include <linux/module.h>
  15 #include <linux/string.h>
  16 #include <linux/netfilter.h>
  17 #include <linux/netfilter_ipv4.h>
  18 #include <net/ip.h>
  19 #include <net/xfrm.h>
  20 
  21 int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb)
  22 {
  23         return xfrm4_extract_header(skb);
  24 }
  25 
  26 static int xfrm4_rcv_encap_finish2(struct net *net, struct sock *sk,
  27                                    struct sk_buff *skb)
  28 {
  29         return dst_input(skb);
  30 }
  31 
  32 static inline int xfrm4_rcv_encap_finish(struct net *net, struct sock *sk,
  33                                          struct sk_buff *skb)
  34 {
  35         if (!skb_dst(skb)) {
  36                 const struct iphdr *iph = ip_hdr(skb);
  37 
  38                 if (ip_route_input_noref(skb, iph->daddr, iph->saddr,
  39                                          iph->tos, skb->dev))
  40                         goto drop;
  41         }
  42 
  43         if (xfrm_trans_queue(skb, xfrm4_rcv_encap_finish2))
  44                 goto drop;
  45 
  46         return 0;
  47 drop:
  48         kfree_skb(skb);
  49         return NET_RX_DROP;
  50 }
  51 
  52 int xfrm4_transport_finish(struct sk_buff *skb, int async)
  53 {
  54         struct xfrm_offload *xo = xfrm_offload(skb);
  55         struct iphdr *iph = ip_hdr(skb);
  56 
  57         iph->protocol = XFRM_MODE_SKB_CB(skb)->protocol;
  58 
  59 #ifndef CONFIG_NETFILTER
  60         if (!async)
  61                 return -iph->protocol;
  62 #endif
  63 
  64         __skb_push(skb, skb->data - skb_network_header(skb));
  65         iph->tot_len = htons(skb->len);
  66         ip_send_check(iph);
  67 
  68         if (xo && (xo->flags & XFRM_GRO)) {
  69                 skb_mac_header_rebuild(skb);
  70                 skb_reset_transport_header(skb);
  71                 return 0;
  72         }
  73 
  74         NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING,
  75                 dev_net(skb->dev), NULL, skb, skb->dev, NULL,
  76                 xfrm4_rcv_encap_finish);
  77         return 0;
  78 }
  79 
  80 /* If it's a keepalive packet, then just eat it.
  81  * If it's an encapsulated packet, then pass it to the
  82  * IPsec xfrm input.
  83  * Returns 0 if skb passed to xfrm or was dropped.
  84  * Returns >0 if skb should be passed to UDP.
  85  * Returns <0 if skb should be resubmitted (-ret is protocol)
  86  */
  87 int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
  88 {
  89         struct udp_sock *up = udp_sk(sk);
  90         struct udphdr *uh;
  91         struct iphdr *iph;
  92         int iphlen, len;
  93 
  94         __u8 *udpdata;
  95         __be32 *udpdata32;
  96         __u16 encap_type = up->encap_type;
  97 
  98         /* if this is not encapsulated socket, then just return now */
  99         if (!encap_type)
 100                 return 1;
 101 
 102         /* If this is a paged skb, make sure we pull up
 103          * whatever data we need to look at. */
 104         len = skb->len - sizeof(struct udphdr);
 105         if (!pskb_may_pull(skb, sizeof(struct udphdr) + min(len, 8)))
 106                 return 1;
 107 
 108         /* Now we can get the pointers */
 109         uh = udp_hdr(skb);
 110         udpdata = (__u8 *)uh + sizeof(struct udphdr);
 111         udpdata32 = (__be32 *)udpdata;
 112 
 113         switch (encap_type) {
 114         default:
 115         case UDP_ENCAP_ESPINUDP:
 116                 /* Check if this is a keepalive packet.  If so, eat it. */
 117                 if (len == 1 && udpdata[0] == 0xff) {
 118                         goto drop;
 119                 } else if (len > sizeof(struct ip_esp_hdr) && udpdata32[0] != 0) {
 120                         /* ESP Packet without Non-ESP header */
 121                         len = sizeof(struct udphdr);
 122                 } else
 123                         /* Must be an IKE packet.. pass it through */
 124                         return 1;
 125                 break;
 126         case UDP_ENCAP_ESPINUDP_NON_IKE:
 127                 /* Check if this is a keepalive packet.  If so, eat it. */
 128                 if (len == 1 && udpdata[0] == 0xff) {
 129                         goto drop;
 130                 } else if (len > 2 * sizeof(u32) + sizeof(struct ip_esp_hdr) &&
 131                            udpdata32[0] == 0 && udpdata32[1] == 0) {
 132 
 133                         /* ESP Packet with Non-IKE marker */
 134                         len = sizeof(struct udphdr) + 2 * sizeof(u32);
 135                 } else
 136                         /* Must be an IKE packet.. pass it through */
 137                         return 1;
 138                 break;
 139         }
 140 
 141         /* At this point we are sure that this is an ESPinUDP packet,
 142          * so we need to remove 'len' bytes from the packet (the UDP
 143          * header and optional ESP marker bytes) and then modify the
 144          * protocol to ESP, and then call into the transform receiver.
 145          */
 146         if (skb_unclone(skb, GFP_ATOMIC))
 147                 goto drop;
 148 
 149         /* Now we can update and verify the packet length... */
 150         iph = ip_hdr(skb);
 151         iphlen = iph->ihl << 2;
 152         iph->tot_len = htons(ntohs(iph->tot_len) - len);
 153         if (skb->len < iphlen + len) {
 154                 /* packet is too small!?! */
 155                 goto drop;
 156         }
 157 
 158         /* pull the data buffer up to the ESP header and set the
 159          * transport header to point to ESP.  Keep UDP on the stack
 160          * for later.
 161          */
 162         __skb_pull(skb, len);
 163         skb_reset_transport_header(skb);
 164 
 165         /* process ESP */
 166         return xfrm4_rcv_encap(skb, IPPROTO_ESP, 0, encap_type);
 167 
 168 drop:
 169         kfree_skb(skb);
 170         return 0;
 171 }
 172 
 173 int xfrm4_rcv(struct sk_buff *skb)
 174 {
 175         return xfrm4_rcv_spi(skb, ip_hdr(skb)->protocol, 0);
 176 }
 177 EXPORT_SYMBOL(xfrm4_rcv);

/* [<][>][^][v][top][bottom][index][help] */