1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*  OpenVPN data channel offload
3  *
4  *  Copyright (C) 2020-2025 OpenVPN, Inc.
5  *
6  *  Author:	Antonio Quartulli <antonio@openvpn.net>
7  *		James Yonan <james@openvpn.net>
8  */
9 
10 #ifndef _NET_OVPN_SKB_H_
11 #define _NET_OVPN_SKB_H_
12 
13 #include <linux/in.h>
14 #include <linux/in6.h>
15 #include <linux/ip.h>
16 #include <linux/ipv6.h>
17 #include <linux/skbuff.h>
18 #include <linux/socket.h>
19 #include <linux/types.h>
20 
21 struct ovpn_cb {
22 	struct ovpn_peer *peer;
23 	struct ovpn_crypto_key_slot *ks;
24 	struct aead_request *req;
25 	struct scatterlist *sg;
26 	u8 *iv;
27 	unsigned int payload_offset;
28 	bool nosignal;
29 };
30 
31 static inline struct ovpn_cb *ovpn_skb_cb(struct sk_buff *skb)
32 {
33 	BUILD_BUG_ON(sizeof(struct ovpn_cb) > sizeof(skb->cb));
34 	return (struct ovpn_cb *)skb->cb;
35 }
36 
37 /* Return IP protocol version from skb header.
38  * Return 0 if protocol is not IPv4/IPv6 or cannot be read.
39  */
40 static inline __be16 ovpn_ip_check_protocol(struct sk_buff *skb)
41 {
42 	__be16 proto = 0;
43 
44 	/* skb could be non-linear,
45 	 * make sure IP header is in non-fragmented part
46 	 */
47 	if (!pskb_network_may_pull(skb, sizeof(struct iphdr)))
48 		return 0;
49 
50 	if (ip_hdr(skb)->version == 4) {
51 		proto = htons(ETH_P_IP);
52 	} else if (ip_hdr(skb)->version == 6) {
53 		if (!pskb_network_may_pull(skb, sizeof(struct ipv6hdr)))
54 			return 0;
55 		proto = htons(ETH_P_IPV6);
56 	}
57 
58 	return proto;
59 }
60 
61 #endif /* _NET_OVPN_SKB_H_ */
62