12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 21da177e4SLinus Torvalds /* 31da177e4SLinus Torvalds * xfrm4_output.c - Common IPsec encapsulation code for IPv4. 41da177e4SLinus Torvalds * Copyright (c) 2004 Herbert Xu <herbert@gondor.apana.org.au> 51da177e4SLinus Torvalds */ 61da177e4SLinus Torvalds 709b8f7a9SHerbert Xu #include <linux/if_ether.h> 809b8f7a9SHerbert Xu #include <linux/kernel.h> 936cf9acfSHerbert Xu #include <linux/module.h> 101da177e4SLinus Torvalds #include <linux/skbuff.h> 1116a6677fSPatrick McHardy #include <linux/netfilter_ipv4.h> 1236cf9acfSHerbert Xu #include <net/dst.h> 131da177e4SLinus Torvalds #include <net/ip.h> 141da177e4SLinus Torvalds #include <net/xfrm.h> 151da177e4SLinus Torvalds #include <net/icmp.h> 161da177e4SLinus Torvalds 170c4b51f0SEric W. Biederman static int __xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb) 185596732fSSteffen Klassert { 195596732fSSteffen Klassert struct xfrm_state *x = skb_dst(skb)->xfrm; 205596732fSSteffen Klassert 215596732fSSteffen Klassert #ifdef CONFIG_NETFILTER 225596732fSSteffen Klassert if (!x) { 235596732fSSteffen Klassert IPCB(skb)->flags |= IPSKB_REROUTED; 2413206b6bSEric W. Biederman return dst_output(net, sk, skb); 255596732fSSteffen Klassert } 265596732fSSteffen Klassert #endif 275596732fSSteffen Klassert 282ab6096dSFlorian Westphal return xfrm_output(sk, skb); 295596732fSSteffen Klassert } 305596732fSSteffen Klassert 31ede2059dSEric W. Biederman int xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb) 3216a6677fSPatrick McHardy { 3329a26a56SEric W. Biederman return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, 3428f8bfd1SPhil Sutter net, sk, skb, skb->dev, skb_dst(skb)->dev, 3529a26a56SEric W. Biederman __xfrm4_output, 3648d5cad8SPatrick McHardy !(IPCB(skb)->flags & IPSKB_REROUTED)); 3716a6677fSPatrick McHardy } 38628e341fSHannes Frederic Sowa 39628e341fSHannes Frederic Sowa void xfrm4_local_error(struct sk_buff *skb, u32 mtu) 40628e341fSHannes Frederic Sowa { 41628e341fSHannes Frederic Sowa struct iphdr *hdr; 42628e341fSHannes Frederic Sowa 43628e341fSHannes Frederic Sowa hdr = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb); 44628e341fSHannes Frederic Sowa ip_local_error(skb->sk, EMSGSIZE, hdr->daddr, 45628e341fSHannes Frederic Sowa inet_sk(skb->sk)->inet_dport, mtu); 46628e341fSHannes Frederic Sowa } 47