net/smc/af_smc.c

Source file repositories/reference/linux-study-clean/net/smc/af_smc.c

File Facts

System
Linux kernel
Corpus path
net/smc/af_smc.c
Extension
.c
Size
93254 bytes
Lines
3608
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 smc_sock_ops = {
	.family		= PF_SMC,
	.owner		= THIS_MODULE,
	.release	= smc_release,
	.bind		= smc_bind,
	.connect	= smc_connect,
	.socketpair	= sock_no_socketpair,
	.accept		= smc_accept,
	.getname	= smc_getname,
	.poll		= smc_poll,
	.ioctl		= smc_ioctl,
	.listen		= smc_listen,
	.shutdown	= smc_shutdown,
	.setsockopt	= smc_setsockopt,
	.getsockopt	= smc_getsockopt,
	.sendmsg	= smc_sendmsg,
	.recvmsg	= smc_recvmsg,
	.mmap		= sock_no_mmap,
	.splice_read	= smc_splice_read,
};

int smc_create_clcsk(struct net *net, struct sock *sk, int family)
{
	struct smc_sock *smc = smc_sk(sk);
	int rc;

	rc = sock_create_kern(net, family, SOCK_STREAM, IPPROTO_TCP,
			      &smc->clcsock);
	if (rc)
		return rc;

	/* smc_clcsock_release() does not wait smc->clcsock->sk's
	 * destruction;  its sk_state might not be TCP_CLOSE after
	 * smc->sk is close()d, and TCP timers can be fired later,
	 * which need net ref.
	 */
	sk = smc->clcsock->sk;
	sk_net_refcnt_upgrade(sk);
	return 0;
}

static int smc_create(struct net *net, struct socket *sock, int protocol,
		      int kern)
{
	int family = (protocol == SMCPROTO_SMC6) ? PF_INET6 : PF_INET;
	struct sock *sk;
	int rc;

	rc = -ESOCKTNOSUPPORT;
	if (sock->type != SOCK_STREAM)
		goto out;

	rc = -EPROTONOSUPPORT;
	if (protocol != SMCPROTO_SMC && protocol != SMCPROTO_SMC6)
		goto out;

	rc = -ENOBUFS;
	sock->ops = &smc_sock_ops;
	sock->state = SS_UNCONNECTED;
	sk = smc_sock_alloc(net, sock, protocol);
	if (!sk)
		goto out;

	rc = smc_create_clcsk(net, sk, family);
	if (rc) {
		sk_common_release(sk);
		sock->sk = NULL;
	}
out:
	return rc;
}

static const struct net_proto_family smc_sock_family_ops = {
	.family	= PF_SMC,
	.owner	= THIS_MODULE,
	.create	= smc_create,
};

unsigned int smc_net_id;

static __net_init int smc_net_init(struct net *net)
{
	int rc;

	rc = smc_sysctl_net_init(net);
	if (rc)
		return rc;
	return smc_pnet_net_init(net);
}

Annotation

Implementation Notes