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