xref: /linux/drivers/net/ovpn/skb.h (revision 8534731dbf2d52a539b94defd06d2a8d3514aacb)
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 };
29 
30 static inline struct ovpn_cb *ovpn_skb_cb(struct sk_buff *skb)
31 {
32 	BUILD_BUG_ON(sizeof(struct ovpn_cb) > sizeof(skb->cb));
33 	return (struct ovpn_cb *)skb->cb;
34 }
35 
36 /* Return IP protocol version from skb header.
37  * Return 0 if protocol is not IPv4/IPv6 or cannot be read.
38  */
39 static inline __be16 ovpn_ip_check_protocol(struct sk_buff *skb)
40 {
41 	__be16 proto = 0;
42 
43 	/* skb could be non-linear,
44 	 * make sure IP header is in non-fragmented part
45 	 */
46 	if (!pskb_network_may_pull(skb, sizeof(struct iphdr)))
47 		return 0;
48 
49 	if (ip_hdr(skb)->version == 4) {
50 		proto = htons(ETH_P_IP);
51 	} else if (ip_hdr(skb)->version == 6) {
52 		if (!pskb_network_may_pull(skb, sizeof(struct ipv6hdr)))
53 			return 0;
54 		proto = htons(ETH_P_IPV6);
55 	}
56 
57 	return proto;
58 }
59 
60 #endif /* _NET_OVPN_SKB_H_ */
61