drivers/net/ovpn/peer.c
Source file repositories/reference/linux-study-clean/drivers/net/ovpn/peer.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ovpn/peer.c- Extension
.c- Size
- 36408 bytes
- Lines
- 1385
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/skbuff.hlinux/list.hlinux/hashtable.hnet/ip6_route.hovpnpriv.hbind.hpktid.hcrypto.hio.hmain.hnetlink.hpeer.hsocket.h
Detected Declarations
function Copyrightfunction llist_for_each_entryfunction ovpn_peer_keepalive_setfunction ovpn_xmit_specialfunction ovpn_peer_reset_sockaddrfunction ovpn_peer_endpoints_updatefunction htonsfunction ovpn_peer_release_rcufunction ovpn_peer_releasefunction ovpn_peer_release_kreffunction ovpn_peer_skb_to_sockaddrfunction ovpn_nexthop_from_skb4function ovpn_nexthop_from_skb6function ovpn_peer_transp_matchfunction ovpn_peer_get_by_transp_addr_p2pfunction hlist_nulls_for_each_entry_rcufunction ovpn_peer_removefunction ovpn_nexthop_from_rt4function ovpn_nexthop_from_rt6function ovpn_peer_check_by_srcfunction ovpn_peer_hash_vpn_ipfunction ovpn_peer_add_mpfunction ovpn_peer_add_p2pfunction ovpn_peer_addfunction ovpn_peer_del_mpfunction ovpn_peer_del_p2pfunction ovpn_peer_delfunction ovpn_peer_release_p2pfunction ovpn_peers_release_mpfunction ovpn_peers_freefunction ovpn_peer_keepalive_work_singlefunction ovpn_peer_keepalive_work_mpfunction hash_for_each_safefunction ovpn_peer_keepalive_work_p2pfunction timers
Annotated Snippet
if (ss->ss_family == AF_INET) {
ip_len = sizeof(struct in_addr);
} else if (ss->ss_family == AF_INET6) {
ip_len = sizeof(struct in6_addr);
} else {
net_dbg_ratelimited("%s: invalid family %u for remote endpoint for peer %u\n",
netdev_name(peer->ovpn->dev),
ss->ss_family, peer->id);
kfree(bind);
return -EINVAL;
}
memcpy(&bind->local, local_ip, ip_len);
}
/* set binding */
ovpn_bind_reset(peer, bind);
return 0;
}
/* variable name __tbl2 needs to be different from __tbl1
* in the macro below to avoid confusing clang
*/
#define ovpn_get_hash_slot(_tbl, _key, _key_len) ({ \
typeof(_tbl) *__tbl2 = &(_tbl); \
jhash(_key, _key_len, 0) % HASH_SIZE(*__tbl2); \
})
#define ovpn_get_hash_head(_tbl, _key, _key_len) ({ \
typeof(_tbl) *__tbl1 = &(_tbl); \
&(*__tbl1)[ovpn_get_hash_slot(*__tbl1, _key, _key_len)];\
})
/**
* ovpn_peer_endpoints_update - update remote or local endpoint for peer
* @peer: peer to update the remote endpoint for
* @skb: incoming packet to retrieve the source/destination address from
*/
void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb)
{
struct hlist_nulls_head *nhead;
struct sockaddr_storage ss;
struct sockaddr_in6 *sa6;
bool reset_cache = false;
struct sockaddr_in *sa;
struct ovpn_bind *bind;
const void *local_ip;
size_t salen = 0;
spin_lock_bh(&peer->lock);
bind = rcu_dereference_protected(peer->bind,
lockdep_is_held(&peer->lock));
if (unlikely(!bind))
goto unlock;
switch (skb->protocol) {
case htons(ETH_P_IP):
/* float check */
if (unlikely(!ovpn_bind_skb_src_match(bind, skb))) {
/* unconditionally save local endpoint in case
* of float, as it may have changed as well
*/
local_ip = &ip_hdr(skb)->daddr;
sa = (struct sockaddr_in *)&ss;
sa->sin_family = AF_INET;
sa->sin_addr.s_addr = ip_hdr(skb)->saddr;
sa->sin_port = udp_hdr(skb)->source;
salen = sizeof(*sa);
reset_cache = true;
break;
}
/* if no float happened, let's double check if the local endpoint
* has changed
*/
if (unlikely(bind->local.ipv4.s_addr != ip_hdr(skb)->daddr)) {
net_dbg_ratelimited("%s: learning local IPv4 for peer %d (%pI4 -> %pI4)\n",
netdev_name(peer->ovpn->dev),
peer->id, &bind->local.ipv4.s_addr,
&ip_hdr(skb)->daddr);
bind->local.ipv4.s_addr = ip_hdr(skb)->daddr;
reset_cache = true;
}
break;
case htons(ETH_P_IPV6):
/* float check */
if (unlikely(!ovpn_bind_skb_src_match(bind, skb))) {
/* unconditionally save local endpoint in case
* of float, as it may have changed as well
Annotation
- Immediate include surface: `linux/skbuff.h`, `linux/list.h`, `linux/hashtable.h`, `net/ip6_route.h`, `ovpnpriv.h`, `bind.h`, `pktid.h`, `crypto.h`.
- Detected declarations: `function Copyright`, `function llist_for_each_entry`, `function ovpn_peer_keepalive_set`, `function ovpn_xmit_special`, `function ovpn_peer_reset_sockaddr`, `function ovpn_peer_endpoints_update`, `function htons`, `function ovpn_peer_release_rcu`, `function ovpn_peer_release`, `function ovpn_peer_release_kref`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.