aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2009-03-30 18:59:17 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2009-04-01 13:24:29 -0400
commitc69da774b28e01e062e0a3aba7509f2dcfd2a11a (patch)
treee406bb8055548fcfcd3796881c263fe44dc69443 /net
parentad5b365c1266b0c9e8e254a3c1cc4ef66bf33cba (diff)
SUNRPC: Ensure IPV6_V6ONLY is set on the socket before binding to a port
Also ensure that we use the protocol family instead of the address family when calling sock_create_kern(). Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/svcsock.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index ac6cd65220c7..9d504234af4a 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1110,7 +1110,6 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
1110 struct svc_sock *svsk; 1110 struct svc_sock *svsk;
1111 struct sock *inet; 1111 struct sock *inet;
1112 int pmap_register = !(flags & SVC_SOCK_ANONYMOUS); 1112 int pmap_register = !(flags & SVC_SOCK_ANONYMOUS);
1113 int val;
1114 1113
1115 dprintk("svc: svc_setup_socket %p\n", sock); 1114 dprintk("svc: svc_setup_socket %p\n", sock);
1116 if (!(svsk = kzalloc(sizeof(*svsk), GFP_KERNEL))) { 1115 if (!(svsk = kzalloc(sizeof(*svsk), GFP_KERNEL))) {
@@ -1143,16 +1142,6 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
1143 else 1142 else
1144 svc_tcp_init(svsk, serv); 1143 svc_tcp_init(svsk, serv);
1145 1144
1146 /*
1147 * If this is a PF_INET6 listener, we want to avoid
1148 * getting requests from IPv4 remotes. Those should
1149 * be shunted to a PF_INET listener via rpcbind.
1150 */
1151 val = 1;
1152 if (inet->sk_family == PF_INET6)
1153 kernel_setsockopt(sock, SOL_IPV6, IPV6_V6ONLY,
1154 (char *)&val, sizeof(val));
1155
1156 dprintk("svc: svc_setup_socket created %p (inet %p)\n", 1145 dprintk("svc: svc_setup_socket created %p (inet %p)\n",
1157 svsk, svsk->sk_sk); 1146 svsk, svsk->sk_sk);
1158 1147
@@ -1220,6 +1209,8 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv,
1220 struct sockaddr_storage addr; 1209 struct sockaddr_storage addr;
1221 struct sockaddr *newsin = (struct sockaddr *)&addr; 1210 struct sockaddr *newsin = (struct sockaddr *)&addr;
1222 int newlen; 1211 int newlen;
1212 int family;
1213 int val;
1223 RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); 1214 RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
1224 1215
1225 dprintk("svc: svc_create_socket(%s, %d, %s)\n", 1216 dprintk("svc: svc_create_socket(%s, %d, %s)\n",
@@ -1231,14 +1222,35 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv,
1231 "sockets supported\n"); 1222 "sockets supported\n");
1232 return ERR_PTR(-EINVAL); 1223 return ERR_PTR(-EINVAL);
1233 } 1224 }
1225
1234 type = (protocol == IPPROTO_UDP)? SOCK_DGRAM : SOCK_STREAM; 1226 type = (protocol == IPPROTO_UDP)? SOCK_DGRAM : SOCK_STREAM;
1227 switch (sin->sa_family) {
1228 case AF_INET6:
1229 family = PF_INET6;
1230 break;
1231 case AF_INET:
1232 family = PF_INET;
1233 break;
1234 default:
1235 return ERR_PTR(-EINVAL);
1236 }
1235 1237
1236 error = sock_create_kern(sin->sa_family, type, protocol, &sock); 1238 error = sock_create_kern(family, type, protocol, &sock);
1237 if (error < 0) 1239 if (error < 0)
1238 return ERR_PTR(error); 1240 return ERR_PTR(error);
1239 1241
1240 svc_reclassify_socket(sock); 1242 svc_reclassify_socket(sock);
1241 1243
1244 /*
1245 * If this is an PF_INET6 listener, we want to avoid
1246 * getting requests from IPv4 remotes. Those should
1247 * be shunted to a PF_INET listener via rpcbind.
1248 */
1249 val = 1;
1250 if (family == PF_INET6)
1251 kernel_setsockopt(sock, SOL_IPV6, IPV6_V6ONLY,
1252 (char *)&val, sizeof(val));
1253
1242 if (type == SOCK_STREAM) 1254 if (type == SOCK_STREAM)
1243 sock->sk->sk_reuse = 1; /* allow address reuse */ 1255 sock->sk->sk_reuse = 1; /* allow address reuse */
1244 error = kernel_bind(sock, sin, len); 1256 error = kernel_bind(sock, sin, len);