/** * xs_setup_udp - Set up transport to use a UDP socket * @xprt: transport to set up * @to: timeout parameters * */ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) { size_t slot_table_size; dprintk("RPC: setting up udp-ipv4 transport...\n"); xprt->max_reqs = xprt_udp_slot_table_entries; slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); xprt->slot = kzalloc(slot_table_size, GFP_KERNEL); if (xprt->slot == NULL) return -ENOMEM; xprt->prot = IPPROTO_UDP; xprt->port = xs_get_random_port(); xprt->tsh_size = 0; xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0; /* XXX: header size can vary due to auth type, IPv6, etc. */ xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); INIT_WORK(&xprt->connect_worker, xs_udp_connect_worker, xprt); xprt->bind_timeout = XS_BIND_TO; xprt->connect_timeout = XS_UDP_CONN_TO; xprt->reestablish_timeout = XS_UDP_REEST_TO; xprt->idle_timeout = XS_IDLE_DISC_TO; xprt->ops = &xs_udp_ops; if (to) xprt->timeout = *to; else xprt_set_timeout(&xprt->timeout, 5, 5 * HZ); return 0; }
/** * xs_setup_tcp - Set up transport to use a TCP socket * @xprt: transport to set up * @to: timeout parameters * */ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) { size_t slot_table_size; dprintk("RPC: setting up tcp-ipv4 transport...\n"); xprt->max_reqs = xprt_tcp_slot_table_entries; slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); xprt->slot = kzalloc(slot_table_size, GFP_KERNEL); if (xprt->slot == NULL) return -ENOMEM; xprt->prot = IPPROTO_TCP; xprt->port = xs_get_random_port(); xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0; xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; INIT_WORK(&xprt->connect_worker, xs_tcp_connect_worker, xprt); xprt->bind_timeout = XS_BIND_TO; xprt->connect_timeout = XS_TCP_CONN_TO; xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; xprt->idle_timeout = XS_IDLE_DISC_TO; xprt->ops = &xs_tcp_ops; if (to) xprt->timeout = *to; else xprt_set_timeout(&xprt->timeout, 2, 60 * HZ); return 0; }
/* * Create the NLM RPC client for an NLM peer */ struct rpc_clnt * nlm_bind_host(struct nlm_host *host) { struct rpc_clnt *clnt; struct rpc_xprt *xprt; dprintk("lockd: nlm_bind_host(%08x)\n", (unsigned)ntohl(host->h_addr.sin_addr.s_addr)); /* Lock host handle */ down(&host->h_sema); /* If we've already created an RPC client, check whether * RPC rebind is required * Note: why keep rebinding if we're on a tcp connection? */ if ((clnt = host->h_rpcclnt) != NULL) { xprt = clnt->cl_xprt; if (!xprt->stream && time_after_eq(jiffies, host->h_nextrebind)) { clnt->cl_port = 0; host->h_nextrebind = jiffies + NLM_HOST_REBIND; dprintk("lockd: next rebind in %ld jiffies\n", host->h_nextrebind - jiffies); } } else { xprt = xprt_create_proto(host->h_proto, &host->h_addr, NULL); if (IS_ERR(xprt)) { dprintk("lockd: xprt_create_proto failed: %ld\n", PTR_ERR(xprt)); goto forgetit; } xprt_set_timeout(&xprt->timeout, 5, nlmsvc_timeout); /* Existing NLM servers accept AUTH_UNIX only */ clnt = rpc_create_client(xprt, host->h_name, &nlm_program, host->h_version, RPC_AUTH_UNIX); if (IS_ERR(clnt)) { xprt_destroy(xprt); dprintk("lockd: rpc_create_client failed: %ld\n", PTR_ERR(clnt)); goto forgetit; } clnt->cl_autobind = 1; /* turn on pmap queries */ xprt->nocong = 1; /* No congestion control for NLM */ xprt->resvport = 1; /* NLM requires a reserved port */ host->h_rpcclnt = clnt; } up(&host->h_sema); return clnt; forgetit: printk("lockd: couldn't create RPC handle for %s\n", host->h_name); up(&host->h_sema); return NULL; }