xref: /linux/drivers/net/ovpn/skb.h (revision ab93e0dd72c37d378dd936f031ffb83ff2bd87ce)
108857b5eSAntonio Quartulli /* SPDX-License-Identifier: GPL-2.0-only */
208857b5eSAntonio Quartulli /*  OpenVPN data channel offload
308857b5eSAntonio Quartulli  *
408857b5eSAntonio Quartulli  *  Copyright (C) 2020-2025 OpenVPN, Inc.
508857b5eSAntonio Quartulli  *
608857b5eSAntonio Quartulli  *  Author:	Antonio Quartulli <antonio@openvpn.net>
708857b5eSAntonio Quartulli  *		James Yonan <james@openvpn.net>
808857b5eSAntonio Quartulli  */
908857b5eSAntonio Quartulli 
1008857b5eSAntonio Quartulli #ifndef _NET_OVPN_SKB_H_
1108857b5eSAntonio Quartulli #define _NET_OVPN_SKB_H_
1208857b5eSAntonio Quartulli 
1308857b5eSAntonio Quartulli #include <linux/in.h>
1408857b5eSAntonio Quartulli #include <linux/in6.h>
1508857b5eSAntonio Quartulli #include <linux/ip.h>
1608857b5eSAntonio Quartulli #include <linux/ipv6.h>
1708857b5eSAntonio Quartulli #include <linux/skbuff.h>
1808857b5eSAntonio Quartulli #include <linux/socket.h>
1908857b5eSAntonio Quartulli #include <linux/types.h>
2008857b5eSAntonio Quartulli 
2108857b5eSAntonio Quartulli struct ovpn_cb {
2208857b5eSAntonio Quartulli 	struct ovpn_peer *peer;
238534731dSAntonio Quartulli 	struct ovpn_crypto_key_slot *ks;
248534731dSAntonio Quartulli 	struct aead_request *req;
258534731dSAntonio Quartulli 	struct scatterlist *sg;
268534731dSAntonio Quartulli 	u8 *iv;
278534731dSAntonio Quartulli 	unsigned int payload_offset;
28*36bb1d71SAntonio Quartulli 	bool nosignal;
2908857b5eSAntonio Quartulli };
3008857b5eSAntonio Quartulli 
ovpn_skb_cb(struct sk_buff * skb)3108857b5eSAntonio Quartulli static inline struct ovpn_cb *ovpn_skb_cb(struct sk_buff *skb)
3208857b5eSAntonio Quartulli {
3308857b5eSAntonio Quartulli 	BUILD_BUG_ON(sizeof(struct ovpn_cb) > sizeof(skb->cb));
3408857b5eSAntonio Quartulli 	return (struct ovpn_cb *)skb->cb;
3508857b5eSAntonio Quartulli }
3608857b5eSAntonio Quartulli 
3708857b5eSAntonio Quartulli /* Return IP protocol version from skb header.
3808857b5eSAntonio Quartulli  * Return 0 if protocol is not IPv4/IPv6 or cannot be read.
3908857b5eSAntonio Quartulli  */
ovpn_ip_check_protocol(struct sk_buff * skb)4008857b5eSAntonio Quartulli static inline __be16 ovpn_ip_check_protocol(struct sk_buff *skb)
4108857b5eSAntonio Quartulli {
4208857b5eSAntonio Quartulli 	__be16 proto = 0;
4308857b5eSAntonio Quartulli 
4408857b5eSAntonio Quartulli 	/* skb could be non-linear,
4508857b5eSAntonio Quartulli 	 * make sure IP header is in non-fragmented part
4608857b5eSAntonio Quartulli 	 */
4708857b5eSAntonio Quartulli 	if (!pskb_network_may_pull(skb, sizeof(struct iphdr)))
4808857b5eSAntonio Quartulli 		return 0;
4908857b5eSAntonio Quartulli 
5008857b5eSAntonio Quartulli 	if (ip_hdr(skb)->version == 4) {
5108857b5eSAntonio Quartulli 		proto = htons(ETH_P_IP);
5208857b5eSAntonio Quartulli 	} else if (ip_hdr(skb)->version == 6) {
5308857b5eSAntonio Quartulli 		if (!pskb_network_may_pull(skb, sizeof(struct ipv6hdr)))
5408857b5eSAntonio Quartulli 			return 0;
5508857b5eSAntonio Quartulli 		proto = htons(ETH_P_IPV6);
5608857b5eSAntonio Quartulli 	}
5708857b5eSAntonio Quartulli 
5808857b5eSAntonio Quartulli 	return proto;
5908857b5eSAntonio Quartulli }
6008857b5eSAntonio Quartulli 
6108857b5eSAntonio Quartulli #endif /* _NET_OVPN_SKB_H_ */
62