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 ---