drivers/net/ovpn/netlink.c
Source file repositories/reference/linux-study-clean/drivers/net/ovpn/netlink.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ovpn/netlink.c- Extension
.c- Size
- 36874 bytes
- Lines
- 1388
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/netdevice.hlinux/types.hnet/genetlink.huapi/linux/ovpn.hovpnpriv.hmain.hnetlink.hnetlink-gen.hbind.hcrypto.hpeer.hsocket.h
Detected Declarations
function ovpn_get_dev_from_attrsfunction ovpn_nl_pre_doitfunction ovpn_nl_post_doitfunction ovpn_nl_attr_sockaddr_remotefunction ovpn_nl_family_getfunction ovpn_nl_peer_precheckfunction modifiedfunction ovpn_nl_peer_new_doitfunction ovpn_nl_peer_set_doitfunction ovpn_nl_send_peerfunction ovpn_nl_peer_get_doitfunction ovpn_nl_peer_get_dumpitfunction hash_for_each_rcufunction ovpn_nl_peer_del_doitfunction ovpn_nl_get_key_dirfunction ovpn_nl_key_new_doitfunction ovpn_nl_send_keyfunction ovpn_nl_key_get_doitfunction ovpn_nl_key_swap_doitfunction ovpn_nl_key_del_doitfunction ovpn_nl_peer_del_notifyfunction ovpn_nl_peer_float_notifyfunction ovpn_nl_key_swap_notifyfunction ovpn_nl_registerfunction ovpn_nl_unregister
Annotated Snippet
if (!ipv6_addr_v4mapped(in6)) {
sin6 = (struct sockaddr_in6 *)ss;
sin6->sin6_port = port;
memcpy(&sin6->sin6_addr, in6, sizeof(*in6));
break;
}
/* v4-mapped-v6 address */
ss->ss_family = AF_INET;
in = &in6->s6_addr32[3];
fallthrough;
case AF_INET:
sin = (struct sockaddr_in *)ss;
sin->sin_port = port;
sin->sin_addr.s_addr = *in;
break;
}
return true;
}
static u8 *ovpn_nl_attr_local_ip(struct nlattr **attrs)
{
u8 *addr6;
if (!attrs[OVPN_A_PEER_LOCAL_IPV4] && !attrs[OVPN_A_PEER_LOCAL_IPV6])
return NULL;
if (attrs[OVPN_A_PEER_LOCAL_IPV4])
return nla_data(attrs[OVPN_A_PEER_LOCAL_IPV4]);
addr6 = nla_data(attrs[OVPN_A_PEER_LOCAL_IPV6]);
/* this is an IPv4-mapped IPv6 address, therefore extract the actual
* v4 address from the last 4 bytes
*/
if (ipv6_addr_v4mapped((struct in6_addr *)addr6))
return addr6 + 12;
return addr6;
}
static sa_family_t ovpn_nl_family_get(struct nlattr *addr4,
struct nlattr *addr6)
{
if (addr4)
return AF_INET;
if (addr6) {
if (ipv6_addr_v4mapped((struct in6_addr *)nla_data(addr6)))
return AF_INET;
return AF_INET6;
}
return AF_UNSPEC;
}
static int ovpn_nl_peer_precheck(struct ovpn_priv *ovpn,
struct genl_info *info,
struct nlattr **attrs)
{
sa_family_t local_fam, remote_fam;
if (NL_REQ_ATTR_CHECK(info->extack, info->attrs[OVPN_A_PEER], attrs,
OVPN_A_PEER_ID))
return -EINVAL;
if (attrs[OVPN_A_PEER_REMOTE_IPV4] && attrs[OVPN_A_PEER_REMOTE_IPV6]) {
NL_SET_ERR_MSG_MOD(info->extack,
"cannot specify both remote IPv4 or IPv6 address");
return -EINVAL;
}
if (!attrs[OVPN_A_PEER_REMOTE_IPV4] &&
!attrs[OVPN_A_PEER_REMOTE_IPV6] && attrs[OVPN_A_PEER_REMOTE_PORT]) {
NL_SET_ERR_MSG_MOD(info->extack,
"cannot specify remote port without IP address");
return -EINVAL;
}
if ((attrs[OVPN_A_PEER_REMOTE_IPV4] ||
attrs[OVPN_A_PEER_REMOTE_IPV6]) &&
!attrs[OVPN_A_PEER_REMOTE_PORT]) {
NL_SET_ERR_MSG_MOD(info->extack,
"cannot specify remote IP address without port");
return -EINVAL;
}
if (!attrs[OVPN_A_PEER_REMOTE_IPV4] &&
attrs[OVPN_A_PEER_LOCAL_IPV4]) {
NL_SET_ERR_MSG_MOD(info->extack,
Annotation
- Immediate include surface: `linux/netdevice.h`, `linux/types.h`, `net/genetlink.h`, `uapi/linux/ovpn.h`, `ovpnpriv.h`, `main.h`, `netlink.h`, `netlink-gen.h`.
- Detected declarations: `function ovpn_get_dev_from_attrs`, `function ovpn_nl_pre_doit`, `function ovpn_nl_post_doit`, `function ovpn_nl_attr_sockaddr_remote`, `function ovpn_nl_family_get`, `function ovpn_nl_peer_precheck`, `function modified`, `function ovpn_nl_peer_new_doit`, `function ovpn_nl_peer_set_doit`, `function ovpn_nl_send_peer`.
- 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.