xref: /openbmc/linux/net/xfrm/xfrm_inout.h (revision 171916cb)
1b3284df1SFlorian Westphal /* SPDX-License-Identifier: GPL-2.0 */
2b3284df1SFlorian Westphal #include <linux/ipv6.h>
3b3284df1SFlorian Westphal #include <net/dsfield.h>
4b3284df1SFlorian Westphal #include <net/xfrm.h>
5b3284df1SFlorian Westphal 
6b3284df1SFlorian Westphal #ifndef XFRM_INOUT_H
7b3284df1SFlorian Westphal #define XFRM_INOUT_H 1
8b3284df1SFlorian Westphal 
xfrm4_extract_header(struct sk_buff * skb)9171916cbSFlorian Westphal static inline void xfrm4_extract_header(struct sk_buff *skb)
10171916cbSFlorian Westphal {
11171916cbSFlorian Westphal 	const struct iphdr *iph = ip_hdr(skb);
12171916cbSFlorian Westphal 
13171916cbSFlorian Westphal 	XFRM_MODE_SKB_CB(skb)->ihl = sizeof(*iph);
14171916cbSFlorian Westphal 	XFRM_MODE_SKB_CB(skb)->id = iph->id;
15171916cbSFlorian Westphal 	XFRM_MODE_SKB_CB(skb)->frag_off = iph->frag_off;
16171916cbSFlorian Westphal 	XFRM_MODE_SKB_CB(skb)->tos = iph->tos;
17171916cbSFlorian Westphal 	XFRM_MODE_SKB_CB(skb)->ttl = iph->ttl;
18171916cbSFlorian Westphal 	XFRM_MODE_SKB_CB(skb)->optlen = iph->ihl * 4 - sizeof(*iph);
19171916cbSFlorian Westphal 	memset(XFRM_MODE_SKB_CB(skb)->flow_lbl, 0,
20171916cbSFlorian Westphal 	       sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl));
21171916cbSFlorian Westphal }
22171916cbSFlorian Westphal 
xfrm6_extract_header(struct sk_buff * skb)23a269fbfcSFlorian Westphal static inline void xfrm6_extract_header(struct sk_buff *skb)
24a269fbfcSFlorian Westphal {
25a269fbfcSFlorian Westphal #if IS_ENABLED(CONFIG_IPV6)
26a269fbfcSFlorian Westphal 	struct ipv6hdr *iph = ipv6_hdr(skb);
27a269fbfcSFlorian Westphal 
28a269fbfcSFlorian Westphal 	XFRM_MODE_SKB_CB(skb)->ihl = sizeof(*iph);
29a269fbfcSFlorian Westphal 	XFRM_MODE_SKB_CB(skb)->id = 0;
30a269fbfcSFlorian Westphal 	XFRM_MODE_SKB_CB(skb)->frag_off = htons(IP_DF);
31a269fbfcSFlorian Westphal 	XFRM_MODE_SKB_CB(skb)->tos = ipv6_get_dsfield(iph);
32a269fbfcSFlorian Westphal 	XFRM_MODE_SKB_CB(skb)->ttl = iph->hop_limit;
33a269fbfcSFlorian Westphal 	XFRM_MODE_SKB_CB(skb)->optlen = 0;
34a269fbfcSFlorian Westphal 	memcpy(XFRM_MODE_SKB_CB(skb)->flow_lbl, iph->flow_lbl,
35a269fbfcSFlorian Westphal 	       sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl));
36a269fbfcSFlorian Westphal #else
37a269fbfcSFlorian Westphal 	WARN_ON_ONCE(1);
38a269fbfcSFlorian Westphal #endif
39a269fbfcSFlorian Westphal }
40a269fbfcSFlorian Westphal 
xfrm6_beet_make_header(struct sk_buff * skb)41b3284df1SFlorian Westphal static inline void xfrm6_beet_make_header(struct sk_buff *skb)
42b3284df1SFlorian Westphal {
43b3284df1SFlorian Westphal 	struct ipv6hdr *iph = ipv6_hdr(skb);
44b3284df1SFlorian Westphal 
45b3284df1SFlorian Westphal 	iph->version = 6;
46b3284df1SFlorian Westphal 
47b3284df1SFlorian Westphal 	memcpy(iph->flow_lbl, XFRM_MODE_SKB_CB(skb)->flow_lbl,
48b3284df1SFlorian Westphal 	       sizeof(iph->flow_lbl));
49b3284df1SFlorian Westphal 	iph->nexthdr = XFRM_MODE_SKB_CB(skb)->protocol;
50b3284df1SFlorian Westphal 
51b3284df1SFlorian Westphal 	ipv6_change_dsfield(iph, 0, XFRM_MODE_SKB_CB(skb)->tos);
52b3284df1SFlorian Westphal 	iph->hop_limit = XFRM_MODE_SKB_CB(skb)->ttl;
53b3284df1SFlorian Westphal }
54b3284df1SFlorian Westphal 
xfrm4_beet_make_header(struct sk_buff * skb)55b3284df1SFlorian Westphal static inline void xfrm4_beet_make_header(struct sk_buff *skb)
56b3284df1SFlorian Westphal {
57b3284df1SFlorian Westphal 	struct iphdr *iph = ip_hdr(skb);
58b3284df1SFlorian Westphal 
59b3284df1SFlorian Westphal 	iph->ihl = 5;
60b3284df1SFlorian Westphal 	iph->version = 4;
61b3284df1SFlorian Westphal 
62b3284df1SFlorian Westphal 	iph->protocol = XFRM_MODE_SKB_CB(skb)->protocol;
63b3284df1SFlorian Westphal 	iph->tos = XFRM_MODE_SKB_CB(skb)->tos;
64b3284df1SFlorian Westphal 
65b3284df1SFlorian Westphal 	iph->id = XFRM_MODE_SKB_CB(skb)->id;
66b3284df1SFlorian Westphal 	iph->frag_off = XFRM_MODE_SKB_CB(skb)->frag_off;
67b3284df1SFlorian Westphal 	iph->ttl = XFRM_MODE_SKB_CB(skb)->ttl;
68b3284df1SFlorian Westphal }
69b3284df1SFlorian Westphal 
70b3284df1SFlorian Westphal #endif
71