~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/ipv4/xfrm4_output.c

Version: ~ [ linux-6.1-rc5 ] ~ [ linux-6.0.8 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.78 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.154 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.224 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.265 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.299 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.333 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.302 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * xfrm4_output.c - Common IPsec encapsulation code for IPv4.
  4  * Copyright (c) 2004 Herbert Xu <herbert@gondor.apana.org.au>
  5  */
  6 
  7 #include <linux/if_ether.h>
  8 #include <linux/kernel.h>
  9 #include <linux/module.h>
 10 #include <linux/skbuff.h>
 11 #include <linux/netfilter_ipv4.h>
 12 #include <net/dst.h>
 13 #include <net/ip.h>
 14 #include <net/xfrm.h>
 15 #include <net/icmp.h>
 16 
 17 static int xfrm4_tunnel_check_size(struct sk_buff *skb)
 18 {
 19         int mtu, ret = 0;
 20 
 21         if (IPCB(skb)->flags & IPSKB_XFRM_TUNNEL_SIZE)
 22                 goto out;
 23 
 24         if (!(ip_hdr(skb)->frag_off & htons(IP_DF)) || skb->ignore_df)
 25                 goto out;
 26 
 27         mtu = dst_mtu(skb_dst(skb));
 28         if ((!skb_is_gso(skb) && skb->len > mtu) ||
 29             (skb_is_gso(skb) &&
 30              !skb_gso_validate_network_len(skb, ip_skb_dst_mtu(skb->sk, skb)))) {
 31                 skb->protocol = htons(ETH_P_IP);
 32 
 33                 if (skb->sk)
 34                         xfrm_local_error(skb, mtu);
 35                 else
 36                         icmp_send(skb, ICMP_DEST_UNREACH,
 37                                   ICMP_FRAG_NEEDED, htonl(mtu));
 38                 ret = -EMSGSIZE;
 39         }
 40 out:
 41         return ret;
 42 }
 43 
 44 int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb)
 45 {
 46         int err;
 47 
 48         err = xfrm4_tunnel_check_size(skb);
 49         if (err)
 50                 return err;
 51 
 52         XFRM_MODE_SKB_CB(skb)->protocol = ip_hdr(skb)->protocol;
 53 
 54         return xfrm4_extract_header(skb);
 55 }
 56 
 57 int xfrm4_output_finish(struct sock *sk, struct sk_buff *skb)
 58 {
 59         memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
 60 
 61 #ifdef CONFIG_NETFILTER
 62         IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
 63 #endif
 64 
 65         return xfrm_output(sk, skb);
 66 }
 67 
 68 static int __xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 69 {
 70         struct xfrm_state *x = skb_dst(skb)->xfrm;
 71         const struct xfrm_state_afinfo *afinfo;
 72         int ret = -EAFNOSUPPORT;
 73 
 74 #ifdef CONFIG_NETFILTER
 75         if (!x) {
 76                 IPCB(skb)->flags |= IPSKB_REROUTED;
 77                 return dst_output(net, sk, skb);
 78         }
 79 #endif
 80 
 81         rcu_read_lock();
 82         afinfo = xfrm_state_afinfo_get_rcu(x->outer_mode.family);
 83         if (likely(afinfo))
 84                 ret = afinfo->output_finish(sk, skb);
 85         else
 86                 kfree_skb(skb);
 87         rcu_read_unlock();
 88 
 89         return ret;
 90 }
 91 
 92 int xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 93 {
 94         return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING,
 95                             net, sk, skb, skb->dev, skb_dst(skb)->dev,
 96                             __xfrm4_output,
 97                             !(IPCB(skb)->flags & IPSKB_REROUTED));
 98 }
 99 
100 void xfrm4_local_error(struct sk_buff *skb, u32 mtu)
101 {
102         struct iphdr *hdr;
103 
104         hdr = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb);
105         ip_local_error(skb->sk, EMSGSIZE, hdr->daddr,
106                        inet_sk(skb->sk)->inet_dport, mtu);
107 }
108 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp