1/* SPDX-License-Identifier: GPL-2.0-only */
2/* OpenVPN data channel offload
3 *
4 * Copyright (C) 2012-2025 OpenVPN, Inc.
5 *
6 * Author: James Yonan <james@openvpn.net>
7 * Antonio Quartulli <antonio@openvpn.net>
8 */
9
10#ifndef _NET_OVPN_OVPNBIND_H_
11#define _NET_OVPN_OVPNBIND_H_
12
13#include <net/ip.h>
14#include <linux/in.h>
15#include <linux/in6.h>
16#include <linux/rcupdate.h>
17#include <linux/skbuff.h>
18#include <linux/spinlock.h>
19
20struct ovpn_peer;
21
22/**
23 * union ovpn_sockaddr - basic transport layer address
24 * @in4: IPv4 address
25 * @in6: IPv6 address
26 */
27union ovpn_sockaddr {
28 struct sockaddr_in in4;
29 struct sockaddr_in6 in6;
30};
31
32/**
33 * struct ovpn_bind - remote peer binding
34 * @remote: the remote peer sockaddress
35 * @local: local endpoint used to talk to the peer
36 * @local.ipv4: local IPv4 used to talk to the peer
37 * @local.ipv6: local IPv6 used to talk to the peer
38 * @rcu: used to schedule RCU cleanup job
39 */
40struct ovpn_bind {
41 union ovpn_sockaddr remote; /* remote sockaddr */
42
43 union {
44 struct in_addr ipv4;
45 struct in6_addr ipv6;
46 } local;
47
48 struct rcu_head rcu;
49};
50
51/**
52 * ovpn_bind_skb_src_match - match packet source with binding
53 * @bind: the binding to match
54 * @skb: the packet to match
55 *
56 * Return: true if the packet source matches the remote peer sockaddr
57 * in the binding
58 */
59static inline bool ovpn_bind_skb_src_match(const struct ovpn_bind *bind,
60 const struct sk_buff *skb)
61{
62 const union ovpn_sockaddr *remote;
63
64 if (unlikely(!bind))
65 return false;
66
67 remote = &bind->remote;
68
69 switch (skb->protocol) {
70 case htons(ETH_P_IP):
71 if (unlikely(remote->in4.sin_family != AF_INET))
72 return false;
73
74 if (unlikely(remote->in4.sin_addr.s_addr != ip_hdr(skb)->saddr))
75 return false;
76
77 if (unlikely(remote->in4.sin_port != udp_hdr(skb)->source))
78 return false;
79 break;
80 case htons(ETH_P_IPV6):
81 if (unlikely(remote->in6.sin6_family != AF_INET6))
82 return false;
83
84 if (unlikely(!ipv6_addr_equal(&remote->in6.sin6_addr,
85 &ipv6_hdr(skb)->saddr)))
86 return false;
87
88 if (unlikely(remote->in6.sin6_port != udp_hdr(skb)->source))
89 return false;
90 break;
91 default:
92 return false;
93 }
94
95 return true;
96}
97
98struct ovpn_bind *ovpn_bind_from_sockaddr(const struct sockaddr_storage *sa);
99void ovpn_bind_reset(struct ovpn_peer *peer, struct ovpn_bind *bind);
100
101#endif /* _NET_OVPN_OVPNBIND_H_ */
102

source code of linux/drivers/net/ovpn/bind.h