net/sunrpc/svc_xprt.c

Source file repositories/reference/linux-study-clean/net/sunrpc/svc_xprt.c

File Facts

System
Linux kernel
Corpus path
net/sunrpc/svc_xprt.c
Extension
.c
Size
43717 bytes
Lines
1595
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: exported/initcall integration point
Status
integration 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

if (IS_ERR(newxprt)) {
			trace_svc_xprt_create_err(serv->sv_programs->pg_name,
						  xcl->xcl_name, sap, len,
						  newxprt);
			module_put(xcl->xcl_owner);
			return PTR_ERR(newxprt);
		}
		newxprt->xpt_cred = get_cred(cred);
		svc_add_new_perm_xprt(serv, newxprt);
		newport = svc_xprt_local_port(newxprt);
		return newport;
	}
 err:
	spin_unlock(&svc_xprt_class_lock);
	/* This errno is exposed to user space.  Provide a reasonable
	 * perror msg for a bad transport. */
	return -EPROTONOSUPPORT;
}

/**
 * svc_xprt_create_from_sa - Add a new listener to @serv from socket address
 * @serv: target RPC service
 * @xprt_name: transport class name
 * @net: network namespace
 * @sap: socket address pointer
 * @flags: SVC_SOCK flags
 * @cred: credential to bind to this transport
 *
 * Return local xprt port on success or %-EPROTONOSUPPORT on failure
 */
int svc_xprt_create_from_sa(struct svc_serv *serv, const char *xprt_name,
			    struct net *net, struct sockaddr *sap,
			    int flags, const struct cred *cred)
{
	size_t len;
	int err;

	switch (sap->sa_family) {
	case AF_INET:
		len = sizeof(struct sockaddr_in);
		break;
#if IS_ENABLED(CONFIG_IPV6)
	case AF_INET6:
		len = sizeof(struct sockaddr_in6);
		break;
#endif
	default:
		return -EAFNOSUPPORT;
	}

	err = _svc_xprt_create(serv, xprt_name, net, sap, len, flags, cred);
	if (err == -EPROTONOSUPPORT) {
		request_module("svc%s", xprt_name);
		err = _svc_xprt_create(serv, xprt_name, net, sap, len, flags,
				       cred);
	}

	return err;
}
EXPORT_SYMBOL_GPL(svc_xprt_create_from_sa);

/**
 * svc_xprt_create - Add a new listener to @serv
 * @serv: target RPC service
 * @xprt_name: transport class name
 * @net: network namespace
 * @family: network address family
 * @port: listener port
 * @flags: SVC_SOCK flags
 * @cred: credential to bind to this transport
 *
 * Return local xprt port on success or %-EPROTONOSUPPORT on failure
 */
int svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
		    struct net *net, const int family,
		    const unsigned short port, int flags,
		    const struct cred *cred)
{
	struct sockaddr_in sin = {
		.sin_family		= AF_INET,
		.sin_addr.s_addr	= htonl(INADDR_ANY),
		.sin_port		= htons(port),
	};
#if IS_ENABLED(CONFIG_IPV6)
	struct sockaddr_in6 sin6 = {
		.sin6_family		= AF_INET6,
		.sin6_addr		= IN6ADDR_ANY_INIT,
		.sin6_port		= htons(port),
	};
#endif

Annotation

Implementation Notes