35
35
#include <linux/errno.h>
36
36
#include <linux/kernel.h>
37
37
#include <linux/in.h>
38
+ #include <linux/ipv6.h>
38
39
#include <linux/poll.h>
39
40
#include <linux/version.h>
40
41
#include <linux/random.h>
@@ -145,26 +146,51 @@ void rds_wake_sk_sleep(struct rds_sock *rs)
145
146
static int rds_getname (struct socket * sock , struct sockaddr * uaddr ,
146
147
int * uaddr_len , int peer )
147
148
{
148
- struct sockaddr_in * sin = (struct sockaddr_in * )uaddr ;
149
149
struct rds_sock * rs = rds_sk_to_rs (sock -> sk );
150
-
151
- memset ( sin -> sin_zero , 0 , sizeof ( sin -> sin_zero )) ;
150
+ struct sockaddr_in6 * sin6 ;
151
+ struct sockaddr_in * sin ;
152
152
153
153
/* racey, don't care */
154
154
if (peer ) {
155
- if (! rs -> rs_conn_addr )
155
+ if (ipv6_addr_any ( & rs -> rs_conn_addr ) )
156
156
return - ENOTCONN ;
157
157
158
- sin -> sin_port = rs -> rs_conn_port ;
159
- sin -> sin_addr .s_addr = rs -> rs_conn_addr ;
158
+ if (ipv6_addr_v4mapped (& rs -> rs_conn_addr )) {
159
+ sin = (struct sockaddr_in * )uaddr ;
160
+ memset (sin -> sin_zero , 0 , sizeof (sin -> sin_zero ));
161
+ sin -> sin_family = AF_INET ;
162
+ sin -> sin_port = rs -> rs_conn_port ;
163
+ sin -> sin_addr .s_addr = rs -> rs_conn_addr_v4 ;
164
+ * uaddr_len = sizeof (* sin );
165
+ } else {
166
+ sin6 = (struct sockaddr_in6 * )uaddr ;
167
+ sin6 -> sin6_family = AF_INET6 ;
168
+ sin6 -> sin6_port = rs -> rs_conn_port ;
169
+ sin6 -> sin6_addr = rs -> rs_conn_addr ;
170
+ sin6 -> sin6_flowinfo = 0 ;
171
+ /* scope_id is the same as in the bound address. */
172
+ sin6 -> sin6_scope_id = rs -> rs_bound_scope_id ;
173
+ * uaddr_len = sizeof (* sin6 );
174
+ }
160
175
} else {
161
- sin -> sin_port = rs -> rs_bound_port ;
162
- sin -> sin_addr .s_addr = rs -> rs_bound_addr ;
176
+ if (ipv6_addr_v4mapped (& rs -> rs_bound_addr )) {
177
+ sin = (struct sockaddr_in * )uaddr ;
178
+ memset (sin -> sin_zero , 0 , sizeof (sin -> sin_zero ));
179
+ sin -> sin_family = AF_INET ;
180
+ sin -> sin_port = rs -> rs_bound_port ;
181
+ sin -> sin_addr .s_addr = rs -> rs_bound_addr_v4 ;
182
+ * uaddr_len = sizeof (* sin );
183
+ } else {
184
+ sin6 = (struct sockaddr_in6 * )uaddr ;
185
+ sin6 -> sin6_family = AF_INET6 ;
186
+ sin6 -> sin6_port = rs -> rs_bound_port ;
187
+ sin6 -> sin6_addr = rs -> rs_bound_addr ;
188
+ sin6 -> sin6_flowinfo = 0 ;
189
+ sin6 -> sin6_scope_id = rs -> rs_bound_scope_id ;
190
+ * uaddr_len = sizeof (* sin6 );
191
+ }
163
192
}
164
193
165
- sin -> sin_family = AF_INET ;
166
-
167
- * uaddr_len = sizeof (* sin );
168
194
return 0 ;
169
195
}
170
196
@@ -269,26 +295,36 @@ static int rds_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
269
295
static int rds_cancel_sent_to (struct rds_sock * rs , char __user * optval ,
270
296
int len )
271
297
{
298
+ struct sockaddr_in6 sin6 ;
272
299
struct sockaddr_in sin ;
273
300
int ret = 0 ;
274
301
275
302
/* racing with another thread binding seems ok here */
276
- if (rs -> rs_bound_addr == 0 ) {
303
+ if (ipv6_addr_any ( & rs -> rs_bound_addr ) ) {
277
304
ret = - ENOTCONN ; /* XXX not a great errno */
278
305
goto out ;
279
306
}
280
307
281
308
if (len < sizeof (struct sockaddr_in )) {
282
309
ret = - EINVAL ;
283
310
goto out ;
311
+ } else if (len < sizeof (struct sockaddr_in6 )) {
312
+ /* Assume IPv4 */
313
+ if (copy_from_user (& sin , optval , sizeof (struct sockaddr_in ))) {
314
+ ret = - EFAULT ;
315
+ goto out ;
316
+ }
317
+ ipv6_addr_set_v4mapped (sin .sin_addr .s_addr , & sin6 .sin6_addr );
318
+ sin6 .sin6_port = sin .sin_port ;
319
+ } else {
320
+ if (copy_from_user (& sin6 , optval ,
321
+ sizeof (struct sockaddr_in6 ))) {
322
+ ret = - EFAULT ;
323
+ goto out ;
324
+ }
284
325
}
285
326
286
- if (copy_from_user (& sin , optval , sizeof (sin ))) {
287
- ret = - EFAULT ;
288
- goto out ;
289
- }
290
-
291
- rds_send_drop_to (rs , & sin );
327
+ rds_send_drop_to (rs , & sin6 );
292
328
out :
293
329
return ret ;
294
330
}
@@ -346,6 +382,7 @@ static int rds_user_reset(struct rds_sock *rs, char __user *optval, int optlen)
346
382
{
347
383
struct rds_reset reset ;
348
384
struct rds_connection * conn ;
385
+ struct in6_addr src6 , dst6 ;
349
386
LIST_HEAD (s_addr_conns );
350
387
351
388
if (optlen != sizeof (struct rds_reset ))
@@ -356,30 +393,32 @@ static int rds_user_reset(struct rds_sock *rs, char __user *optval, int optlen)
356
393
return - EFAULT ;
357
394
358
395
/* Reset all conns associated with source addr */
396
+ ipv6_addr_set_v4mapped (reset .src .s_addr , & src6 );
359
397
if (reset .dst .s_addr == 0 ) {
360
398
pr_info ("RDS: Reset ALL conns for Source %pI4\n" ,
361
399
& reset .src .s_addr );
362
400
363
401
rds_conn_laddr_list (sock_net (rds_rs_to_sk (rs )),
364
- reset . src . s_addr , & s_addr_conns );
402
+ & src6 , & s_addr_conns );
365
403
if (list_empty (& s_addr_conns ))
366
404
goto done ;
367
405
368
406
list_for_each_entry (conn , & s_addr_conns , c_laddr_node )
369
407
if (conn )
370
- rds_user_conn_paths_drop (conn , 1 );
408
+ rds_conn_drop (conn , DR_USER_RESET );
371
409
goto done ;
372
410
}
373
411
374
- conn = rds_conn_find (sock_net (rds_rs_to_sk (rs )),
375
- reset .src .s_addr , reset .dst .s_addr ,
376
- rs -> rs_transport , reset .tos );
412
+ ipv6_addr_set_v4mapped (reset .dst .s_addr , & dst6 );
413
+ conn = rds_conn_find (sock_net (rds_rs_to_sk (rs )), & src6 , & dst6 ,
414
+ rs -> rs_transport , reset .tos ,
415
+ rs -> rs_bound_scope_id );
377
416
378
417
if (conn ) {
379
418
bool is_tcp = conn -> c_trans -> t_type == RDS_TRANS_TCP ;
380
419
381
420
printk (KERN_NOTICE "Resetting RDS/%s connection <%pI4,%pI4,%d>\n" ,
382
- is_tcp ? "tcp " : "IB" ,
421
+ is_tcp ? "TCP " : "IB" ,
383
422
& reset .src .s_addr ,
384
423
& reset .dst .s_addr , conn -> c_tos );
385
424
rds_user_conn_paths_drop (conn , DR_USER_RESET );
@@ -571,31 +610,41 @@ static int rds_connect(struct socket *sock, struct sockaddr *uaddr,
571
610
int addr_len , int flags )
572
611
{
573
612
struct sock * sk = sock -> sk ;
574
- struct sockaddr_in * sin = ( struct sockaddr_in * ) uaddr ;
613
+ struct sockaddr_in * sin ;
575
614
struct rds_sock * rs = rds_sk_to_rs (sk );
576
615
int ret = 0 ;
577
616
578
617
lock_sock (sk );
579
618
580
- if (addr_len != sizeof (struct sockaddr_in )) {
581
- ret = - EINVAL ;
582
- goto out ;
583
- }
619
+ switch (addr_len ) {
620
+ case sizeof (struct sockaddr_in ):
621
+ sin = (struct sockaddr_in * )uaddr ;
622
+ if (sin -> sin_family != AF_INET ) {
623
+ ret = - EAFNOSUPPORT ;
624
+ break ;
625
+ }
626
+ if (sin -> sin_addr .s_addr == INADDR_ANY ) {
627
+ ret = - EDESTADDRREQ ;
628
+ break ;
629
+ }
630
+ if (IN_MULTICAST (ntohl (sin -> sin_addr .s_addr )) ||
631
+ sin -> sin_addr .s_addr == INADDR_BROADCAST ) {
632
+ ret = - EINVAL ;
633
+ break ;
634
+ }
635
+ ipv6_addr_set_v4mapped (sin -> sin_addr .s_addr , & rs -> rs_conn_addr );
636
+ rs -> rs_conn_port = sin -> sin_port ;
637
+ break ;
584
638
585
- if (sin -> sin_family != AF_INET ) {
586
- ret = - EAFNOSUPPORT ;
587
- goto out ;
588
- }
639
+ case sizeof (struct sockaddr_in6 ):
640
+ ret = - EPROTONOSUPPORT ;
641
+ break ;
589
642
590
- if ( sin -> sin_addr . s_addr == htonl ( INADDR_ANY )) {
591
- ret = - EDESTADDRREQ ;
592
- goto out ;
643
+ default :
644
+ ret = - EINVAL ;
645
+ break ;
593
646
}
594
647
595
- rs -> rs_conn_addr = sin -> sin_addr .s_addr ;
596
- rs -> rs_conn_port = sin -> sin_port ;
597
-
598
- out :
599
648
release_sock (sk );
600
649
return ret ;
601
650
}
@@ -659,8 +708,10 @@ static int __rds_create(struct socket *sock, struct sock *sk, int protocol)
659
708
rs -> rs_netfilter_enabled = 0 ;
660
709
rs -> rs_rx_traces = 0 ;
661
710
662
- if (rs -> rs_bound_addr )
663
- printk (KERN_CRIT "bound addr %x at create\n" , rs -> rs_bound_addr );
711
+ if (!ipv6_addr_any (& rs -> rs_bound_addr )) {
712
+ printk (KERN_CRIT "bound addr %pI6c at create\n" ,
713
+ & rs -> rs_bound_addr );
714
+ }
664
715
665
716
spin_lock_bh (& rds_sock_lock );
666
717
list_add_tail (& rs -> rs_item , & rds_sock_list );
@@ -756,8 +807,10 @@ static void rds_sock_inc_info(struct socket *sock, unsigned int len,
756
807
list_for_each_entry (inc , & rs -> rs_recv_queue , i_item ) {
757
808
total ++ ;
758
809
if (total <= len )
759
- rds_inc_info_copy (inc , iter , inc -> i_saddr ,
760
- rs -> rs_bound_addr , 1 );
810
+ rds_inc_info_copy (inc , iter ,
811
+ inc -> i_saddr .s6_addr32 [3 ],
812
+ rs -> rs_bound_addr_v4 ,
813
+ 1 );
761
814
}
762
815
763
816
read_unlock (& rs -> rs_recv_lock );
@@ -786,8 +839,8 @@ static void rds_sock_info(struct socket *sock, unsigned int len,
786
839
list_for_each_entry (rs , & rds_sock_list , rs_item ) {
787
840
sinfo .sndbuf = rds_sk_sndbuf (rs );
788
841
sinfo .rcvbuf = rds_sk_rcvbuf (rs );
789
- sinfo .bound_addr = rs -> rs_bound_addr ;
790
- sinfo .connected_addr = rs -> rs_conn_addr ;
842
+ sinfo .bound_addr = rs -> rs_bound_addr_v4 ;
843
+ sinfo .connected_addr = rs -> rs_conn_addr_v4 ;
791
844
sinfo .bound_port = rs -> rs_bound_port ;
792
845
sinfo .connected_port = rs -> rs_conn_port ;
793
846
sinfo .inum = sock_i_ino (rds_rs_to_sk (rs ));
@@ -913,8 +966,8 @@ static void __exit rds_exit(void)
913
966
rds_page_exit ();
914
967
rds_info_deregister_func (RDS_INFO_SOCKETS , rds_sock_info );
915
968
rds_info_deregister_func (RDS_INFO_RECV_MESSAGES , rds_sock_inc_info );
916
-
917
969
}
970
+
918
971
module_exit (rds_exit );
919
972
920
973
u32 rds_gen_num ;
0 commit comments