af_rds.c (c13aca79ff3c4af5fd31a5b2743a90eba6e36a26) | af_rds.c (eee2fa6ab3225192d6d894c54a6fb02ac9efdff6) |
---|---|
1/* | 1/* |
2 * Copyright (c) 2006 Oracle. All rights reserved. | 2 * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved. |
3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or --- 19 unchanged lines hidden (view full) --- 30 * SOFTWARE. 31 * 32 */ 33#include <linux/module.h> 34#include <linux/errno.h> 35#include <linux/kernel.h> 36#include <linux/gfp.h> 37#include <linux/in.h> | 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or --- 19 unchanged lines hidden (view full) --- 30 * SOFTWARE. 31 * 32 */ 33#include <linux/module.h> 34#include <linux/errno.h> 35#include <linux/kernel.h> 36#include <linux/gfp.h> 37#include <linux/in.h> |
38#include <linux/ipv6.h> |
|
38#include <linux/poll.h> 39#include <net/sock.h> 40 41#include "rds.h" 42 43/* this is just used for stats gathering :/ */ 44static DEFINE_SPINLOCK(rds_sock_lock); 45static unsigned long rds_sock_count; --- 62 unchanged lines hidden (view full) --- 108 read_lock_irqsave(&rs->rs_recv_lock, flags); 109 __rds_wake_sk_sleep(rds_rs_to_sk(rs)); 110 read_unlock_irqrestore(&rs->rs_recv_lock, flags); 111} 112 113static int rds_getname(struct socket *sock, struct sockaddr *uaddr, 114 int peer) 115{ | 39#include <linux/poll.h> 40#include <net/sock.h> 41 42#include "rds.h" 43 44/* this is just used for stats gathering :/ */ 45static DEFINE_SPINLOCK(rds_sock_lock); 46static unsigned long rds_sock_count; --- 62 unchanged lines hidden (view full) --- 109 read_lock_irqsave(&rs->rs_recv_lock, flags); 110 __rds_wake_sk_sleep(rds_rs_to_sk(rs)); 111 read_unlock_irqrestore(&rs->rs_recv_lock, flags); 112} 113 114static int rds_getname(struct socket *sock, struct sockaddr *uaddr, 115 int peer) 116{ |
116 struct sockaddr_in *sin = (struct sockaddr_in *)uaddr; | |
117 struct rds_sock *rs = rds_sk_to_rs(sock->sk); | 117 struct rds_sock *rs = rds_sk_to_rs(sock->sk); |
118 struct sockaddr_in6 *sin6; 119 struct sockaddr_in *sin; 120 int uaddr_len; |
|
118 | 121 |
119 memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 120 | |
121 /* racey, don't care */ 122 if (peer) { | 122 /* racey, don't care */ 123 if (peer) { |
123 if (!rs->rs_conn_addr) | 124 if (ipv6_addr_any(&rs->rs_conn_addr)) |
124 return -ENOTCONN; 125 | 125 return -ENOTCONN; 126 |
126 sin->sin_port = rs->rs_conn_port; 127 sin->sin_addr.s_addr = rs->rs_conn_addr; | 127 if (ipv6_addr_v4mapped(&rs->rs_conn_addr)) { 128 sin = (struct sockaddr_in *)uaddr; 129 memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 130 sin->sin_family = AF_INET; 131 sin->sin_port = rs->rs_conn_port; 132 sin->sin_addr.s_addr = rs->rs_conn_addr_v4; 133 uaddr_len = sizeof(*sin); 134 } else { 135 sin6 = (struct sockaddr_in6 *)uaddr; 136 sin6->sin6_family = AF_INET6; 137 sin6->sin6_port = rs->rs_conn_port; 138 sin6->sin6_addr = rs->rs_conn_addr; 139 sin6->sin6_flowinfo = 0; 140 /* scope_id is the same as in the bound address. */ 141 sin6->sin6_scope_id = rs->rs_bound_scope_id; 142 uaddr_len = sizeof(*sin6); 143 } |
128 } else { | 144 } else { |
129 sin->sin_port = rs->rs_bound_port; 130 sin->sin_addr.s_addr = rs->rs_bound_addr; | 145 /* If socket is not yet bound, set the return address family 146 * to be AF_UNSPEC (value 0) and the address size to be that 147 * of an IPv4 address. 148 */ 149 if (ipv6_addr_any(&rs->rs_bound_addr)) { 150 sin = (struct sockaddr_in *)uaddr; 151 memset(sin, 0, sizeof(*sin)); 152 sin->sin_family = AF_UNSPEC; 153 return sizeof(*sin); 154 } 155 if (ipv6_addr_v4mapped(&rs->rs_bound_addr)) { 156 sin = (struct sockaddr_in *)uaddr; 157 memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 158 sin->sin_family = AF_INET; 159 sin->sin_port = rs->rs_bound_port; 160 sin->sin_addr.s_addr = rs->rs_bound_addr_v4; 161 uaddr_len = sizeof(*sin); 162 } else { 163 sin6 = (struct sockaddr_in6 *)uaddr; 164 sin6->sin6_family = AF_INET6; 165 sin6->sin6_port = rs->rs_bound_port; 166 sin6->sin6_addr = rs->rs_bound_addr; 167 sin6->sin6_flowinfo = 0; 168 sin6->sin6_scope_id = rs->rs_bound_scope_id; 169 uaddr_len = sizeof(*sin6); 170 } |
131 } 132 | 171 } 172 |
133 sin->sin_family = AF_INET; 134 135 return sizeof(*sin); | 173 return uaddr_len; |
136} 137 138/* 139 * RDS' poll is without a doubt the least intuitive part of the interface, 140 * as EPOLLIN and EPOLLOUT do not behave entirely as you would expect from 141 * a network protocol. 142 * 143 * EPOLLIN is asserted if --- 54 unchanged lines hidden (view full) --- 198static int rds_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 199{ 200 return -ENOIOCTLCMD; 201} 202 203static int rds_cancel_sent_to(struct rds_sock *rs, char __user *optval, 204 int len) 205{ | 174} 175 176/* 177 * RDS' poll is without a doubt the least intuitive part of the interface, 178 * as EPOLLIN and EPOLLOUT do not behave entirely as you would expect from 179 * a network protocol. 180 * 181 * EPOLLIN is asserted if --- 54 unchanged lines hidden (view full) --- 236static int rds_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 237{ 238 return -ENOIOCTLCMD; 239} 240 241static int rds_cancel_sent_to(struct rds_sock *rs, char __user *optval, 242 int len) 243{ |
244 struct sockaddr_in6 sin6; |
|
206 struct sockaddr_in sin; 207 int ret = 0; 208 209 /* racing with another thread binding seems ok here */ | 245 struct sockaddr_in sin; 246 int ret = 0; 247 248 /* racing with another thread binding seems ok here */ |
210 if (rs->rs_bound_addr == 0) { | 249 if (ipv6_addr_any(&rs->rs_bound_addr)) { |
211 ret = -ENOTCONN; /* XXX not a great errno */ 212 goto out; 213 } 214 215 if (len < sizeof(struct sockaddr_in)) { 216 ret = -EINVAL; 217 goto out; | 250 ret = -ENOTCONN; /* XXX not a great errno */ 251 goto out; 252 } 253 254 if (len < sizeof(struct sockaddr_in)) { 255 ret = -EINVAL; 256 goto out; |
257 } else if (len < sizeof(struct sockaddr_in6)) { 258 /* Assume IPv4 */ 259 if (copy_from_user(&sin, optval, sizeof(struct sockaddr_in))) { 260 ret = -EFAULT; 261 goto out; 262 } 263 ipv6_addr_set_v4mapped(sin.sin_addr.s_addr, &sin6.sin6_addr); 264 sin6.sin6_port = sin.sin_port; 265 } else { 266 if (copy_from_user(&sin6, optval, 267 sizeof(struct sockaddr_in6))) { 268 ret = -EFAULT; 269 goto out; 270 } |
|
218 } 219 | 271 } 272 |
220 if (copy_from_user(&sin, optval, sizeof(sin))) { 221 ret = -EFAULT; 222 goto out; 223 } 224 225 rds_send_drop_to(rs, &sin); | 273 rds_send_drop_to(rs, &sin6); |
226out: 227 return ret; 228} 229 230static int rds_set_bool_option(unsigned char *optvar, char __user *optval, 231 int optlen) 232{ 233 int value; --- 196 unchanged lines hidden (view full) --- 430 return ret; 431 432} 433 434static int rds_connect(struct socket *sock, struct sockaddr *uaddr, 435 int addr_len, int flags) 436{ 437 struct sock *sk = sock->sk; | 274out: 275 return ret; 276} 277 278static int rds_set_bool_option(unsigned char *optvar, char __user *optval, 279 int optlen) 280{ 281 int value; --- 196 unchanged lines hidden (view full) --- 478 return ret; 479 480} 481 482static int rds_connect(struct socket *sock, struct sockaddr *uaddr, 483 int addr_len, int flags) 484{ 485 struct sock *sk = sock->sk; |
438 struct sockaddr_in *sin = (struct sockaddr_in *)uaddr; | 486 struct sockaddr_in *sin; |
439 struct rds_sock *rs = rds_sk_to_rs(sk); 440 int ret = 0; 441 442 lock_sock(sk); 443 | 487 struct rds_sock *rs = rds_sk_to_rs(sk); 488 int ret = 0; 489 490 lock_sock(sk); 491 |
444 if (addr_len != sizeof(struct sockaddr_in)) { 445 ret = -EINVAL; 446 goto out; 447 } | 492 switch (addr_len) { 493 case sizeof(struct sockaddr_in): 494 sin = (struct sockaddr_in *)uaddr; 495 if (sin->sin_family != AF_INET) { 496 ret = -EAFNOSUPPORT; 497 break; 498 } 499 if (sin->sin_addr.s_addr == htonl(INADDR_ANY)) { 500 ret = -EDESTADDRREQ; 501 break; 502 } 503 if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) || 504 sin->sin_addr.s_addr == htonl(INADDR_BROADCAST)) { 505 ret = -EINVAL; 506 break; 507 } 508 ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &rs->rs_conn_addr); 509 rs->rs_conn_port = sin->sin_port; 510 break; |
448 | 511 |
449 if (sin->sin_family != AF_INET) { 450 ret = -EAFNOSUPPORT; 451 goto out; 452 } | 512 case sizeof(struct sockaddr_in6): 513 ret = -EPROTONOSUPPORT; 514 break; |
453 | 515 |
454 if (sin->sin_addr.s_addr == htonl(INADDR_ANY)) { 455 ret = -EDESTADDRREQ; 456 goto out; | 516 default: 517 ret = -EINVAL; 518 break; |
457 } 458 | 519 } 520 |
459 rs->rs_conn_addr = sin->sin_addr.s_addr; 460 rs->rs_conn_port = sin->sin_port; 461 462out: | |
463 release_sock(sk); 464 return ret; 465} 466 467static struct proto rds_proto = { 468 .name = "RDS", 469 .owner = THIS_MODULE, 470 .obj_size = sizeof(struct rds_sock), --- 102 unchanged lines hidden (view full) --- 573 574 list_for_each_entry(rs, &rds_sock_list, rs_item) { 575 read_lock(&rs->rs_recv_lock); 576 577 /* XXX too lazy to maintain counts.. */ 578 list_for_each_entry(inc, &rs->rs_recv_queue, i_item) { 579 total++; 580 if (total <= len) | 521 release_sock(sk); 522 return ret; 523} 524 525static struct proto rds_proto = { 526 .name = "RDS", 527 .owner = THIS_MODULE, 528 .obj_size = sizeof(struct rds_sock), --- 102 unchanged lines hidden (view full) --- 631 632 list_for_each_entry(rs, &rds_sock_list, rs_item) { 633 read_lock(&rs->rs_recv_lock); 634 635 /* XXX too lazy to maintain counts.. */ 636 list_for_each_entry(inc, &rs->rs_recv_queue, i_item) { 637 total++; 638 if (total <= len) |
581 rds_inc_info_copy(inc, iter, inc->i_saddr, 582 rs->rs_bound_addr, 1); | 639 rds_inc_info_copy(inc, iter, 640 inc->i_saddr.s6_addr32[3], 641 rs->rs_bound_addr_v4, 642 1); |
583 } 584 585 read_unlock(&rs->rs_recv_lock); 586 } 587 588 spin_unlock_bh(&rds_sock_lock); 589 590 lens->nr = total; --- 12 unchanged lines hidden (view full) --- 603 spin_lock_bh(&rds_sock_lock); 604 605 if (len < rds_sock_count) 606 goto out; 607 608 list_for_each_entry(rs, &rds_sock_list, rs_item) { 609 sinfo.sndbuf = rds_sk_sndbuf(rs); 610 sinfo.rcvbuf = rds_sk_rcvbuf(rs); | 643 } 644 645 read_unlock(&rs->rs_recv_lock); 646 } 647 648 spin_unlock_bh(&rds_sock_lock); 649 650 lens->nr = total; --- 12 unchanged lines hidden (view full) --- 663 spin_lock_bh(&rds_sock_lock); 664 665 if (len < rds_sock_count) 666 goto out; 667 668 list_for_each_entry(rs, &rds_sock_list, rs_item) { 669 sinfo.sndbuf = rds_sk_sndbuf(rs); 670 sinfo.rcvbuf = rds_sk_rcvbuf(rs); |
611 sinfo.bound_addr = rs->rs_bound_addr; 612 sinfo.connected_addr = rs->rs_conn_addr; | 671 sinfo.bound_addr = rs->rs_bound_addr_v4; 672 sinfo.connected_addr = rs->rs_conn_addr_v4; |
613 sinfo.bound_port = rs->rs_bound_port; 614 sinfo.connected_port = rs->rs_conn_port; 615 sinfo.inum = sock_i_ino(rds_rs_to_sk(rs)); 616 617 rds_info_copy(iter, &sinfo, sizeof(sinfo)); 618 } 619 620out: --- 87 unchanged lines hidden --- | 673 sinfo.bound_port = rs->rs_bound_port; 674 sinfo.connected_port = rs->rs_conn_port; 675 sinfo.inum = sock_i_ino(rds_rs_to_sk(rs)); 676 677 rds_info_copy(iter, &sinfo, sizeof(sinfo)); 678 } 679 680out: --- 87 unchanged lines hidden --- |