aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/xprtsock.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index cd7c18b24527..8295ae28391a 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1261,6 +1261,39 @@ static int xs_bind4(struct sock_xprt *transport, struct socket *sock)
1261 return err; 1261 return err;
1262} 1262}
1263 1263
1264static int xs_bind6(struct sock_xprt *transport, struct socket *sock)
1265{
1266 struct sockaddr_in6 myaddr = {
1267 .sin6_family = AF_INET6,
1268 };
1269 struct sockaddr_in6 *sa;
1270 int err;
1271 unsigned short port = transport->port;
1272
1273 if (!transport->xprt.resvport)
1274 port = 0;
1275 sa = (struct sockaddr_in6 *)&transport->addr;
1276 myaddr.sin6_addr = sa->sin6_addr;
1277 do {
1278 myaddr.sin6_port = htons(port);
1279 err = kernel_bind(sock, (struct sockaddr *) &myaddr,
1280 sizeof(myaddr));
1281 if (!transport->xprt.resvport)
1282 break;
1283 if (err == 0) {
1284 transport->port = port;
1285 break;
1286 }
1287 if (port <= xprt_min_resvport)
1288 port = xprt_max_resvport;
1289 else
1290 port--;
1291 } while (err == -EADDRINUSE && port != transport->port);
1292 dprintk("RPC: xs_bind6 "NIP6_FMT":%u: %s (%d)\n",
1293 NIP6(myaddr.sin6_addr), port, err ? "failed" : "ok", err);
1294 return err;
1295}
1296
1264#ifdef CONFIG_DEBUG_LOCK_ALLOC 1297#ifdef CONFIG_DEBUG_LOCK_ALLOC
1265static struct lock_class_key xs_key[2]; 1298static struct lock_class_key xs_key[2];
1266static struct lock_class_key xs_slock_key[2]; 1299static struct lock_class_key xs_slock_key[2];