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