net/l2tp/l2tp_ip.c

Source file repositories/reference/linux-study-clean/net/l2tp/l2tp_ip.c

File Facts

System
Linux kernel
Corpus path
net/l2tp/l2tp_ip.c
Extension
.c
Size
17361 bytes
Lines
737
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.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct proto_ops l2tp_ip_ops = {
	.family		   = PF_INET,
	.owner		   = THIS_MODULE,
	.release	   = inet_release,
	.bind		   = inet_bind,
	.connect	   = inet_dgram_connect,
	.socketpair	   = sock_no_socketpair,
	.accept		   = sock_no_accept,
	.getname	   = l2tp_ip_getname,
	.poll		   = datagram_poll,
	.ioctl		   = inet_ioctl,
	.gettstamp	   = sock_gettstamp,
	.listen		   = sock_no_listen,
	.shutdown	   = inet_shutdown,
	.setsockopt	   = sock_common_setsockopt,
	.getsockopt	   = sock_common_getsockopt,
	.sendmsg	   = inet_sendmsg,
	.recvmsg	   = sock_common_recvmsg,
	.mmap		   = sock_no_mmap,
};

static struct inet_protosw l2tp_ip_protosw = {
	.type		= SOCK_DGRAM,
	.protocol	= IPPROTO_L2TP,
	.prot		= &l2tp_ip_prot,
	.ops		= &l2tp_ip_ops,
};

static struct net_protocol l2tp_ip_protocol __read_mostly = {
	.handler	= l2tp_ip_recv,
};

static __net_init int l2tp_ip_init_net(struct net *net)
{
	struct l2tp_ip_net *pn = net_generic(net, l2tp_ip_net_id);

	rwlock_init(&pn->l2tp_ip_lock);
	INIT_HLIST_HEAD(&pn->l2tp_ip_table);
	INIT_HLIST_HEAD(&pn->l2tp_ip_bind_table);
	return 0;
}

static __net_exit void l2tp_ip_exit_net(struct net *net)
{
	struct l2tp_ip_net *pn = l2tp_ip_pernet(net);

	write_lock_bh(&pn->l2tp_ip_lock);
	WARN_ON_ONCE(hlist_count_nodes(&pn->l2tp_ip_table) != 0);
	WARN_ON_ONCE(hlist_count_nodes(&pn->l2tp_ip_bind_table) != 0);
	write_unlock_bh(&pn->l2tp_ip_lock);
}

static struct pernet_operations l2tp_ip_net_ops = {
	.init = l2tp_ip_init_net,
	.exit = l2tp_ip_exit_net,
	.id   = &l2tp_ip_net_id,
	.size = sizeof(struct l2tp_ip_net),
};

static int __init l2tp_ip_init(void)
{
	int err;

	pr_info("L2TP IP encapsulation support (L2TPv3)\n");

	err = register_pernet_device(&l2tp_ip_net_ops);
	if (err)
		goto out;

	err = proto_register(&l2tp_ip_prot, 1);
	if (err != 0)
		goto out1;

	err = inet_add_protocol(&l2tp_ip_protocol, IPPROTO_L2TP);
	if (err)
		goto out2;

	inet_register_protosw(&l2tp_ip_protosw);
	return 0;

out2:
	proto_unregister(&l2tp_ip_prot);
out1:
	unregister_pernet_device(&l2tp_ip_net_ops);
out:
	return err;
}

static void __exit l2tp_ip_exit(void)
{

Annotation

Implementation Notes