162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * xfrm4_output.c - Common IPsec encapsulation code for IPv4. 462306a36Sopenharmony_ci * Copyright (c) 2004 Herbert Xu <herbert@gondor.apana.org.au> 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <linux/if_ether.h> 862306a36Sopenharmony_ci#include <linux/kernel.h> 962306a36Sopenharmony_ci#include <linux/module.h> 1062306a36Sopenharmony_ci#include <linux/skbuff.h> 1162306a36Sopenharmony_ci#include <linux/netfilter_ipv4.h> 1262306a36Sopenharmony_ci#include <net/dst.h> 1362306a36Sopenharmony_ci#include <net/ip.h> 1462306a36Sopenharmony_ci#include <net/xfrm.h> 1562306a36Sopenharmony_ci#include <net/icmp.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_cistatic int __xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb) 1862306a36Sopenharmony_ci{ 1962306a36Sopenharmony_ci#ifdef CONFIG_NETFILTER 2062306a36Sopenharmony_ci struct xfrm_state *x = skb_dst(skb)->xfrm; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci if (!x) { 2362306a36Sopenharmony_ci IPCB(skb)->flags |= IPSKB_REROUTED; 2462306a36Sopenharmony_ci return dst_output(net, sk, skb); 2562306a36Sopenharmony_ci } 2662306a36Sopenharmony_ci#endif 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci return xfrm_output(sk, skb); 2962306a36Sopenharmony_ci} 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ciint xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb) 3262306a36Sopenharmony_ci{ 3362306a36Sopenharmony_ci return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, 3462306a36Sopenharmony_ci net, sk, skb, skb->dev, skb_dst(skb)->dev, 3562306a36Sopenharmony_ci __xfrm4_output, 3662306a36Sopenharmony_ci !(IPCB(skb)->flags & IPSKB_REROUTED)); 3762306a36Sopenharmony_ci} 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_civoid xfrm4_local_error(struct sk_buff *skb, u32 mtu) 4062306a36Sopenharmony_ci{ 4162306a36Sopenharmony_ci struct iphdr *hdr; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci hdr = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb); 4462306a36Sopenharmony_ci ip_local_error(skb->sk, EMSGSIZE, hdr->daddr, 4562306a36Sopenharmony_ci inet_sk(skb->sk)->inet_dport, mtu); 4662306a36Sopenharmony_ci} 47