diff --git a/fs/afs/cell.c b/fs/afs/cell.c index 5523fa3c05d907927fb185af1993a1a4fbde4aef..216821fd1a610698c90a53ec3581602803c09e64 100644 --- a/fs/afs/cell.c +++ b/fs/afs/cell.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "internal.h" @@ -86,28 +87,38 @@ static struct afs_cell *afs_cell_alloc(struct afs_net *net, delimiter = ','; } else { + if (strchr(vllist, ',') || !strchr(vllist, '.')) + delimiter = ','; _vllist = vllist; } /* fill in the VL server list from the rest of the string */ do { struct sockaddr_rxrpc *srx = &cell->vl_addrs[cell->vl_naddrs]; - unsigned a, b, c, d; + const char *end; next = strchr(_vllist, delimiter); if (next) *next++ = 0; - if (sscanf(_vllist, "%u.%u.%u.%u", &a, &b, &c, &d) != 4) - goto bad_address; - - if (a > 255 || b > 255 || c > 255 || d > 255) + if (in4_pton(_vllist, -1, (u8 *)&srx->transport.sin6.sin6_addr.s6_addr32[3], + -1, &end)) { + srx->transport_len = sizeof(struct sockaddr_in6); + srx->transport.sin6.sin6_family = AF_INET6; + srx->transport.sin6.sin6_flowinfo = 0; + srx->transport.sin6.sin6_scope_id = 0; + srx->transport.sin6.sin6_addr.s6_addr32[0] = 0; + srx->transport.sin6.sin6_addr.s6_addr32[1] = 0; + srx->transport.sin6.sin6_addr.s6_addr32[2] = htonl(0xffff); + } else if (in6_pton(_vllist, -1, srx->transport.sin6.sin6_addr.s6_addr, + -1, &end)) { + srx->transport_len = sizeof(struct sockaddr_in6); + srx->transport.sin6.sin6_family = AF_INET6; + srx->transport.sin6.sin6_flowinfo = 0; + srx->transport.sin6.sin6_scope_id = 0; + } else { goto bad_address; - - srx->transport_len = sizeof(struct sockaddr_in); - srx->transport.sin.sin_family = AF_INET; - srx->transport.sin.sin_addr.s_addr = - htonl((a << 24) | (b << 16) | (c << 8) | d); + } } while (cell->vl_naddrs++, cell->vl_naddrs < AFS_CELL_MAX_ADDRS && (_vllist = next)); diff --git a/fs/afs/proc.c b/fs/afs/proc.c index f76018104ae03489e7683f18ea8ee149f77a389e..d00d550ff2ef12ed9ac29a932ebcc904faccacd3 100644 --- a/fs/afs/proc.c +++ b/fs/afs/proc.c @@ -662,7 +662,7 @@ static int afs_proc_cell_servers_show(struct seq_file *m, void *v) /* display one cell per line on subsequent lines */ sprintf(ipaddr, "%pISp", &server->addr.transport); - seq_printf(m, "%3d %-15.15s %5d\n", + seq_printf(m, "%3d %-15s %5d\n", atomic_read(&server->usage), ipaddr, server->fs_state); return 0; diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index c108effb54be3af1182dc657342467e0c63a975a..5d2c1a34ffd5f578b6d2c256909835bea441d574 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c @@ -46,21 +46,20 @@ int afs_open_socket(struct afs_net *net) _enter(""); - ret = sock_create_kern(&init_net, AF_RXRPC, SOCK_DGRAM, PF_INET, &socket); + ret = sock_create_kern(&init_net, AF_RXRPC, SOCK_DGRAM, PF_INET6, &socket); if (ret < 0) goto error_1; socket->sk->sk_allocation = GFP_NOFS; /* bind the callback manager's address to make this a server socket */ + memset(&srx, 0, sizeof(srx)); srx.srx_family = AF_RXRPC; srx.srx_service = CM_SERVICE; srx.transport_type = SOCK_DGRAM; - srx.transport_len = sizeof(srx.transport.sin); - srx.transport.sin.sin_family = AF_INET; - srx.transport.sin.sin_port = htons(AFS_CM_PORT); - memset(&srx.transport.sin.sin_addr, 0, - sizeof(srx.transport.sin.sin_addr)); + srx.transport_len = sizeof(srx.transport.sin6); + srx.transport.sin6.sin6_family = AF_INET6; + srx.transport.sin6.sin6_port = htons(AFS_CM_PORT); ret = kernel_bind(socket, (struct sockaddr *) &srx, sizeof(srx)); if (ret < 0) diff --git a/fs/afs/server.c b/fs/afs/server.c index 662f7fbf5d050af539d3b72ddc1a825c2990622b..c63974f06385453f22ca9753cc79e3014ef1ea06 100644 --- a/fs/afs/server.c +++ b/fs/afs/server.c @@ -200,11 +200,6 @@ struct afs_server *afs_find_server(struct afs_net *net, _enter("{%d,%pIS}", srx->transport.family, &srx->transport); - if (srx->transport.family != AF_INET) { - WARN(true, "AFS does not yes support non-IPv4 addresses\n"); - return NULL; - } - read_lock(&net->servers_lock); p = net->servers.rb_node; diff --git a/fs/afs/vlclient.c b/fs/afs/vlclient.c index 48d137628d6a9d5769bd5db6ffa77ed8c43ae5fc..276319aa86d8b25336d75bbc9d12170260bba8f5 100644 --- a/fs/afs/vlclient.c +++ b/fs/afs/vlclient.c @@ -88,10 +88,15 @@ static int afs_deliver_vl_get_entry_by_xxx(struct afs_call *call) entry->servers[loop].srx_family = AF_RXRPC; entry->servers[loop].srx_service = FS_SERVICE; entry->servers[loop].transport_type = SOCK_DGRAM; - entry->servers[loop].transport_len = sizeof(entry->servers[loop].transport.sin); - entry->servers[loop].transport.sin.sin_family = AF_INET; - entry->servers[loop].transport.sin.sin_port = htons(AFS_FS_PORT); - entry->servers[loop].transport.sin.sin_addr.s_addr = *bp++; + entry->servers[loop].transport_len = sizeof(entry->servers[loop].transport.sin6); + entry->servers[loop].transport.sin6.sin6_family = AF_INET6; + entry->servers[loop].transport.sin6.sin6_port = htons(AFS_FS_PORT); + entry->servers[loop].transport.sin6.sin6_flowinfo = 0; + entry->servers[loop].transport.sin6.sin6_scope_id = 0; + entry->servers[loop].transport.sin6.sin6_addr.s6_addr32[0] = 0; + entry->servers[loop].transport.sin6.sin6_addr.s6_addr32[1] = 0; + entry->servers[loop].transport.sin6.sin6_addr.s6_addr32[2] = htonl(0xffff); + entry->servers[loop].transport.sin6.sin6_addr.s6_addr32[3] = *bp++; } bp += 8; /* partition IDs */