net/l2tp/l2tp_ppp.c
Source file repositories/reference/linux-study-clean/net/l2tp/l2tp_ppp.c
File Facts
- System
- Linux kernel
- Corpus path
net/l2tp/l2tp_ppp.c- Extension
.c- Size
- 43354 bytes
- Lines
- 1731
- Domain
- Networking Core
- Bucket
- Sockets, Protocols, Packet Path, And Network Policy
- Inferred role
- Networking Core: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/module.hlinux/string.hlinux/list.hlinux/uaccess.hlinux/uio.hlinux/kernel.hlinux/spinlock.hlinux/kthread.hlinux/sched.hlinux/slab.hlinux/errno.hlinux/jiffies.hlinux/netdevice.hlinux/net.hlinux/inetdevice.hlinux/skbuff.hlinux/init.hlinux/ip.hlinux/udp.hlinux/if_pppox.hlinux/if_pppol2tp.hnet/sock.hlinux/ppp_channel.hlinux/ppp_defs.hlinux/ppp-ioctl.hlinux/file.hlinux/hash.hlinux/sort.hlinux/proc_fs.hlinux/l2tp.hlinux/nsproxy.hnet/net_namespace.h
Detected Declarations
struct pppol2tp_sessionstruct l2tp_connect_infostruct pppol2tp_seq_datafunction pppol2tp_recvmsgfunction pppol2tp_recvfunction sendmsgfunction pppol2tp_sendmsgfunction Sessionfunction pppol2tp_session_closefunction pppol2tp_releasefunction pppol2tp_backlog_recvfunction pppol2tp_createfunction pppol2tp_showfunction pppol2tp_session_initfunction pppol2tp_sockaddr_get_infofunction pppol2tp_tunnel_mtufunction pppol2tp_connectfunction ioctlfunction pppol2tp_session_createfunction pppol2tp_getnamefunction ioctlfunction pppol2tp_tunnel_copy_statsfunction pppol2tp_ioctlfunction setsockoptfunction pppol2tp_session_setsockoptfunction pppol2tp_setsockoptfunction pppol2tp_tunnel_getsockoptfunction pppol2tp_session_getsockoptfunction pppol2tp_getsockoptfunction pppol2tp_next_tunnelfunction pppol2tp_next_sessionfunction pppol2tp_seq_stopfunction pppol2tp_next_tunnelfunction pppol2tp_seq_tunnel_showfunction pppol2tp_seq_session_showfunction pppol2tp_seq_showfunction pppol2tp_init_netfunction pppol2tp_exit_netfunction pppol2tp_initfunction pppol2tp_exitmodule init pppol2tp_init
Annotated Snippet
static const struct proto_ops pppol2tp_ops;
/* Retrieves the pppol2tp socket associated to a session. */
static struct sock *pppol2tp_session_get_sock(struct l2tp_session *session)
{
struct pppol2tp_session *ps = l2tp_session_priv(session);
return rcu_dereference(ps->sk);
}
/* Helpers to obtain tunnel/session contexts from sockets.
*/
static struct l2tp_session *pppol2tp_sock_to_session(struct sock *sk)
{
struct l2tp_session *session;
if (!sk)
return NULL;
rcu_read_lock();
session = rcu_dereference_sk_user_data(sk);
if (session && refcount_inc_not_zero(&session->ref_count)) {
rcu_read_unlock();
WARN_ON_ONCE(session->magic != L2TP_SESSION_MAGIC);
return session;
}
rcu_read_unlock();
return NULL;
}
/*****************************************************************************
* Receive data handling
*****************************************************************************/
/* Receive message. This is the recvmsg for the PPPoL2TP socket.
*/
static int pppol2tp_recvmsg(struct socket *sock, struct msghdr *msg,
size_t len, int flags)
{
int err;
struct sk_buff *skb;
struct sock *sk = sock->sk;
err = -EIO;
if (sk->sk_state & PPPOX_BOUND)
goto end;
err = 0;
skb = skb_recv_datagram(sk, flags, &err);
if (!skb)
goto end;
if (len > skb->len)
len = skb->len;
else if (len < skb->len)
msg->msg_flags |= MSG_TRUNC;
err = skb_copy_datagram_msg(skb, 0, msg, len);
if (likely(err == 0))
err = len;
kfree_skb(skb);
end:
return err;
}
static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len)
{
struct sock *sk;
/* If the socket is bound, send it in to PPP's input queue. Otherwise
* queue it on the session socket.
*/
rcu_read_lock();
sk = pppol2tp_session_get_sock(session);
if (!sk)
goto no_sock;
/* If the first two bytes are 0xFF03, consider that it is the PPP's
* Address and Control fields and skip them. The L2TP module has always
* worked this way, although, in theory, the use of these fields should
* be negotiated and handled at the PPP layer. These fields are
* constant: 0xFF is the All-Stations Address and 0x03 the Unnumbered
* Information command with Poll/Final bit set to zero (RFC 1662).
*/
if (pskb_may_pull(skb, 2) && skb->data[0] == PPP_ALLSTATIONS &&
skb->data[1] == PPP_UI)
skb_pull(skb, 2);
Annotation
- Immediate include surface: `linux/module.h`, `linux/string.h`, `linux/list.h`, `linux/uaccess.h`, `linux/uio.h`, `linux/kernel.h`, `linux/spinlock.h`, `linux/kthread.h`.
- Detected declarations: `struct pppol2tp_session`, `struct l2tp_connect_info`, `struct pppol2tp_seq_data`, `function pppol2tp_recvmsg`, `function pppol2tp_recv`, `function sendmsg`, `function pppol2tp_sendmsg`, `function Session`, `function pppol2tp_session_close`, `function pppol2tp_release`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.