aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/clnt.c1
-rw-r--r--net/sunrpc/xprtsock.c96
2 files changed, 95 insertions, 2 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index c1e467e1b07d..7389804e3bb7 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -288,6 +288,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
288 .srcaddr = args->saddress, 288 .srcaddr = args->saddress,
289 .dstaddr = args->address, 289 .dstaddr = args->address,
290 .addrlen = args->addrsize, 290 .addrlen = args->addrsize,
291 .bc_xprt = args->bc_xprt,
291 }; 292 };
292 char servername[48]; 293 char servername[48];
293 294
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index d9a2b815714e..bee415465754 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2468,11 +2468,93 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args)
2468 return ERR_PTR(-EINVAL); 2468 return ERR_PTR(-EINVAL);
2469} 2469}
2470 2470
2471/**
2472 * xs_setup_bc_tcp - Set up transport to use a TCP backchannel socket
2473 * @args: rpc transport creation arguments
2474 *
2475 */
2476static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
2477{
2478 struct sockaddr *addr = args->dstaddr;
2479 struct rpc_xprt *xprt;
2480 struct sock_xprt *transport;
2481 struct svc_sock *bc_sock;
2482
2483 if (!args->bc_xprt)
2484 ERR_PTR(-EINVAL);
2485
2486 xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries);
2487 if (IS_ERR(xprt))
2488 return xprt;
2489 transport = container_of(xprt, struct sock_xprt, xprt);
2490
2491 xprt->prot = IPPROTO_TCP;
2492 xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32);
2493 xprt->max_payload = RPC_MAX_FRAGMENT_SIZE;
2494 xprt->timeout = &xs_tcp_default_timeout;
2495
2496 /* backchannel */
2497 xprt_set_bound(xprt);
2498 xprt->bind_timeout = 0;
2499 xprt->connect_timeout = 0;
2500 xprt->reestablish_timeout = 0;
2501 xprt->idle_timeout = 0;
2502
2503 /*
2504 * The backchannel uses the same socket connection as the
2505 * forechannel
2506 */
2507 xprt->bc_xprt = args->bc_xprt;
2508 bc_sock = container_of(args->bc_xprt, struct svc_sock, sk_xprt);
2509 bc_sock->sk_bc_xprt = xprt;
2510 transport->sock = bc_sock->sk_sock;
2511 transport->inet = bc_sock->sk_sk;
2512
2513 xprt->ops = &bc_tcp_ops;
2514
2515 switch (addr->sa_family) {
2516 case AF_INET:
2517 xs_format_peer_addresses(xprt, "tcp",
2518 RPCBIND_NETID_TCP);
2519 break;
2520 case AF_INET6:
2521 xs_format_peer_addresses(xprt, "tcp",
2522 RPCBIND_NETID_TCP6);
2523 break;
2524 default:
2525 kfree(xprt);
2526 return ERR_PTR(-EAFNOSUPPORT);
2527 }
2528
2529 if (xprt_bound(xprt))
2530 dprintk("RPC: set up xprt to %s (port %s) via %s\n",
2531 xprt->address_strings[RPC_DISPLAY_ADDR],
2532 xprt->address_strings[RPC_DISPLAY_PORT],
2533 xprt->address_strings[RPC_DISPLAY_PROTO]);
2534 else
2535 dprintk("RPC: set up xprt to %s (autobind) via %s\n",
2536 xprt->address_strings[RPC_DISPLAY_ADDR],
2537 xprt->address_strings[RPC_DISPLAY_PROTO]);
2538
2539 /*
2540 * Since we don't want connections for the backchannel, we set
2541 * the xprt status to connected
2542 */
2543 xprt_set_connected(xprt);
2544
2545
2546 if (try_module_get(THIS_MODULE))
2547 return xprt;
2548 kfree(xprt->slot);
2549 kfree(xprt);
2550 return ERR_PTR(-EINVAL);
2551}
2552
2471static struct xprt_class xs_udp_transport = { 2553static struct xprt_class xs_udp_transport = {
2472 .list = LIST_HEAD_INIT(xs_udp_transport.list), 2554 .list = LIST_HEAD_INIT(xs_udp_transport.list),
2473 .name = "udp", 2555 .name = "udp",
2474 .owner = THIS_MODULE, 2556 .owner = THIS_MODULE,
2475 .ident = IPPROTO_UDP, 2557 .ident = XPRT_TRANSPORT_UDP,
2476 .setup = xs_setup_udp, 2558 .setup = xs_setup_udp,
2477}; 2559};
2478 2560
@@ -2480,10 +2562,18 @@ static struct xprt_class xs_tcp_transport = {
2480 .list = LIST_HEAD_INIT(xs_tcp_transport.list), 2562 .list = LIST_HEAD_INIT(xs_tcp_transport.list),
2481 .name = "tcp", 2563 .name = "tcp",
2482 .owner = THIS_MODULE, 2564 .owner = THIS_MODULE,
2483 .ident = IPPROTO_TCP, 2565 .ident = XPRT_TRANSPORT_TCP,
2484 .setup = xs_setup_tcp, 2566 .setup = xs_setup_tcp,
2485}; 2567};
2486 2568
2569static struct xprt_class xs_bc_tcp_transport = {
2570 .list = LIST_HEAD_INIT(xs_bc_tcp_transport.list),
2571 .name = "tcp NFSv4.1 backchannel",
2572 .owner = THIS_MODULE,
2573 .ident = XPRT_TRANSPORT_BC_TCP,
2574 .setup = xs_setup_bc_tcp,
2575};
2576
2487/** 2577/**
2488 * init_socket_xprt - set up xprtsock's sysctls, register with RPC client 2578 * init_socket_xprt - set up xprtsock's sysctls, register with RPC client
2489 * 2579 *
@@ -2497,6 +2587,7 @@ int init_socket_xprt(void)
2497 2587
2498 xprt_register_transport(&xs_udp_transport); 2588 xprt_register_transport(&xs_udp_transport);
2499 xprt_register_transport(&xs_tcp_transport); 2589 xprt_register_transport(&xs_tcp_transport);
2590 xprt_register_transport(&xs_bc_tcp_transport);
2500 2591
2501 return 0; 2592 return 0;
2502} 2593}
@@ -2516,6 +2607,7 @@ void cleanup_socket_xprt(void)
2516 2607
2517 xprt_unregister_transport(&xs_udp_transport); 2608 xprt_unregister_transport(&xs_udp_transport);
2518 xprt_unregister_transport(&xs_tcp_transport); 2609 xprt_unregister_transport(&xs_tcp_transport);
2610 xprt_unregister_transport(&xs_bc_tcp_transport);
2519} 2611}
2520 2612
2521static int param_set_uint_minmax(const char *val, struct kernel_param *kp, 2613static int param_set_uint_minmax(const char *val, struct kernel_param *kp,