aboutsummaryrefslogtreecommitdiffstats
path: root/net/rds/connection.c
diff options
context:
space:
mode:
authorKa-Cheong Poon <ka-cheong.poon@oracle.com>2018-07-23 23:51:23 -0400
committerDavid S. Miller <davem@davemloft.net>2018-07-24 00:17:44 -0400
commitb7ff8b1036f0b0df1390ba6b5e9bc7ec458e857a (patch)
tree398bab1a171b7da3be14fe9f7f1d5936032b7f74 /net/rds/connection.c
parent1e2b44e78eead7bcadfbf96f70d95773191541c9 (diff)
rds: Extend RDS API for IPv6 support
There are many data structures (RDS socket options) used by RDS apps which use a 32 bit integer to store IP address. To support IPv6, struct in6_addr needs to be used. To ensure backward compatibility, a new data structure is introduced for each of those data structures which use a 32 bit integer to represent an IP address. And new socket options are introduced to use those new structures. This means that existing apps should work without a problem with the new RDS module. For apps which want to use IPv6, those new data structures and socket options can be used. IPv4 mapped address is used to represent IPv4 address in the new data structures. v4: Revert changes to SO_RDS_TRANSPORT Signed-off-by: Ka-Cheong Poon <ka-cheong.poon@oracle.com> Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/rds/connection.c')
-rw-r--r--net/rds/connection.c101
1 files changed, 93 insertions, 8 deletions
diff --git a/net/rds/connection.c b/net/rds/connection.c
index 5c9ceed55dae..051e35c1e7c6 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -498,16 +498,19 @@ EXPORT_SYMBOL_GPL(rds_conn_destroy);
498 498
499static void __rds_inc_msg_cp(struct rds_incoming *inc, 499static void __rds_inc_msg_cp(struct rds_incoming *inc,
500 struct rds_info_iterator *iter, 500 struct rds_info_iterator *iter,
501 void *saddr, void *daddr, int flip) 501 void *saddr, void *daddr, int flip, bool isv6)
502{ 502{
503 rds_inc_info_copy(inc, iter, *(__be32 *)saddr, 503 if (isv6)
504 *(__be32 *)daddr, flip); 504 rds6_inc_info_copy(inc, iter, saddr, daddr, flip);
505 else
506 rds_inc_info_copy(inc, iter, *(__be32 *)saddr,
507 *(__be32 *)daddr, flip);
505} 508}
506 509
507static void rds_conn_message_info_cmn(struct socket *sock, unsigned int len, 510static void rds_conn_message_info_cmn(struct socket *sock, unsigned int len,
508 struct rds_info_iterator *iter, 511 struct rds_info_iterator *iter,
509 struct rds_info_lengths *lens, 512 struct rds_info_lengths *lens,
510 int want_send) 513 int want_send, bool isv6)
511{ 514{
512 struct hlist_head *head; 515 struct hlist_head *head;
513 struct list_head *list; 516 struct list_head *list;
@@ -518,7 +521,10 @@ static void rds_conn_message_info_cmn(struct socket *sock, unsigned int len,
518 size_t i; 521 size_t i;
519 int j; 522 int j;
520 523
521 len /= sizeof(struct rds_info_message); 524 if (isv6)
525 len /= sizeof(struct rds6_info_message);
526 else
527 len /= sizeof(struct rds_info_message);
522 528
523 rcu_read_lock(); 529 rcu_read_lock();
524 530
@@ -528,6 +534,9 @@ static void rds_conn_message_info_cmn(struct socket *sock, unsigned int len,
528 struct rds_conn_path *cp; 534 struct rds_conn_path *cp;
529 int npaths; 535 int npaths;
530 536
537 if (!isv6 && conn->c_isv6)
538 continue;
539
531 npaths = (conn->c_trans->t_mp_capable ? 540 npaths = (conn->c_trans->t_mp_capable ?
532 RDS_MPATH_WORKERS : 1); 541 RDS_MPATH_WORKERS : 1);
533 542
@@ -548,7 +557,7 @@ static void rds_conn_message_info_cmn(struct socket *sock, unsigned int len,
548 iter, 557 iter,
549 &conn->c_laddr, 558 &conn->c_laddr,
550 &conn->c_faddr, 559 &conn->c_faddr,
551 0); 560 0, isv6);
552 } 561 }
553 562
554 spin_unlock_irqrestore(&cp->cp_lock, flags); 563 spin_unlock_irqrestore(&cp->cp_lock, flags);
@@ -558,7 +567,10 @@ static void rds_conn_message_info_cmn(struct socket *sock, unsigned int len,
558 rcu_read_unlock(); 567 rcu_read_unlock();
559 568
560 lens->nr = total; 569 lens->nr = total;
561 lens->each = sizeof(struct rds_info_message); 570 if (isv6)
571 lens->each = sizeof(struct rds6_info_message);
572 else
573 lens->each = sizeof(struct rds_info_message);
562} 574}
563 575
564static void rds_conn_message_info(struct socket *sock, unsigned int len, 576static void rds_conn_message_info(struct socket *sock, unsigned int len,
@@ -566,7 +578,15 @@ static void rds_conn_message_info(struct socket *sock, unsigned int len,
566 struct rds_info_lengths *lens, 578 struct rds_info_lengths *lens,
567 int want_send) 579 int want_send)
568{ 580{
569 rds_conn_message_info_cmn(sock, len, iter, lens, want_send); 581 rds_conn_message_info_cmn(sock, len, iter, lens, want_send, false);
582}
583
584static void rds6_conn_message_info(struct socket *sock, unsigned int len,
585 struct rds_info_iterator *iter,
586 struct rds_info_lengths *lens,
587 int want_send)
588{
589 rds_conn_message_info_cmn(sock, len, iter, lens, want_send, true);
570} 590}
571 591
572static void rds_conn_message_info_send(struct socket *sock, unsigned int len, 592static void rds_conn_message_info_send(struct socket *sock, unsigned int len,
@@ -576,6 +596,13 @@ static void rds_conn_message_info_send(struct socket *sock, unsigned int len,
576 rds_conn_message_info(sock, len, iter, lens, 1); 596 rds_conn_message_info(sock, len, iter, lens, 1);
577} 597}
578 598
599static void rds6_conn_message_info_send(struct socket *sock, unsigned int len,
600 struct rds_info_iterator *iter,
601 struct rds_info_lengths *lens)
602{
603 rds6_conn_message_info(sock, len, iter, lens, 1);
604}
605
579static void rds_conn_message_info_retrans(struct socket *sock, 606static void rds_conn_message_info_retrans(struct socket *sock,
580 unsigned int len, 607 unsigned int len,
581 struct rds_info_iterator *iter, 608 struct rds_info_iterator *iter,
@@ -584,6 +611,14 @@ static void rds_conn_message_info_retrans(struct socket *sock,
584 rds_conn_message_info(sock, len, iter, lens, 0); 611 rds_conn_message_info(sock, len, iter, lens, 0);
585} 612}
586 613
614static void rds6_conn_message_info_retrans(struct socket *sock,
615 unsigned int len,
616 struct rds_info_iterator *iter,
617 struct rds_info_lengths *lens)
618{
619 rds6_conn_message_info(sock, len, iter, lens, 0);
620}
621
587void rds_for_each_conn_info(struct socket *sock, unsigned int len, 622void rds_for_each_conn_info(struct socket *sock, unsigned int len,
588 struct rds_info_iterator *iter, 623 struct rds_info_iterator *iter,
589 struct rds_info_lengths *lens, 624 struct rds_info_lengths *lens,
@@ -699,6 +734,34 @@ static int rds_conn_info_visitor(struct rds_conn_path *cp, void *buffer)
699 return 1; 734 return 1;
700} 735}
701 736
737static int rds6_conn_info_visitor(struct rds_conn_path *cp, void *buffer)
738{
739 struct rds6_info_connection *cinfo6 = buffer;
740 struct rds_connection *conn = cp->cp_conn;
741
742 cinfo6->next_tx_seq = cp->cp_next_tx_seq;
743 cinfo6->next_rx_seq = cp->cp_next_rx_seq;
744 cinfo6->laddr = conn->c_laddr;
745 cinfo6->faddr = conn->c_faddr;
746 strncpy(cinfo6->transport, conn->c_trans->t_name,
747 sizeof(cinfo6->transport));
748 cinfo6->flags = 0;
749
750 rds_conn_info_set(cinfo6->flags, test_bit(RDS_IN_XMIT, &cp->cp_flags),
751 SENDING);
752 /* XXX Future: return the state rather than these funky bits */
753 rds_conn_info_set(cinfo6->flags,
754 atomic_read(&cp->cp_state) == RDS_CONN_CONNECTING,
755 CONNECTING);
756 rds_conn_info_set(cinfo6->flags,
757 atomic_read(&cp->cp_state) == RDS_CONN_UP,
758 CONNECTED);
759 /* Just return 1 as there is no error case. This is a helper function
760 * for rds_walk_conn_path_info() and it wants a return value.
761 */
762 return 1;
763}
764
702static void rds_conn_info(struct socket *sock, unsigned int len, 765static void rds_conn_info(struct socket *sock, unsigned int len,
703 struct rds_info_iterator *iter, 766 struct rds_info_iterator *iter,
704 struct rds_info_lengths *lens) 767 struct rds_info_lengths *lens)
@@ -711,6 +774,18 @@ static void rds_conn_info(struct socket *sock, unsigned int len,
711 sizeof(struct rds_info_connection)); 774 sizeof(struct rds_info_connection));
712} 775}
713 776
777static void rds6_conn_info(struct socket *sock, unsigned int len,
778 struct rds_info_iterator *iter,
779 struct rds_info_lengths *lens)
780{
781 u64 buffer[(sizeof(struct rds6_info_connection) + 7) / 8];
782
783 rds_walk_conn_path_info(sock, len, iter, lens,
784 rds6_conn_info_visitor,
785 buffer,
786 sizeof(struct rds6_info_connection));
787}
788
714int rds_conn_init(void) 789int rds_conn_init(void)
715{ 790{
716 int ret; 791 int ret;
@@ -732,6 +807,11 @@ int rds_conn_init(void)
732 rds_conn_message_info_send); 807 rds_conn_message_info_send);
733 rds_info_register_func(RDS_INFO_RETRANS_MESSAGES, 808 rds_info_register_func(RDS_INFO_RETRANS_MESSAGES,
734 rds_conn_message_info_retrans); 809 rds_conn_message_info_retrans);
810 rds_info_register_func(RDS6_INFO_CONNECTIONS, rds6_conn_info);
811 rds_info_register_func(RDS6_INFO_SEND_MESSAGES,
812 rds6_conn_message_info_send);
813 rds_info_register_func(RDS6_INFO_RETRANS_MESSAGES,
814 rds6_conn_message_info_retrans);
735 815
736 return 0; 816 return 0;
737} 817}
@@ -750,6 +830,11 @@ void rds_conn_exit(void)
750 rds_conn_message_info_send); 830 rds_conn_message_info_send);
751 rds_info_deregister_func(RDS_INFO_RETRANS_MESSAGES, 831 rds_info_deregister_func(RDS_INFO_RETRANS_MESSAGES,
752 rds_conn_message_info_retrans); 832 rds_conn_message_info_retrans);
833 rds_info_deregister_func(RDS6_INFO_CONNECTIONS, rds6_conn_info);
834 rds_info_deregister_func(RDS6_INFO_SEND_MESSAGES,
835 rds6_conn_message_info_send);
836 rds_info_deregister_func(RDS6_INFO_RETRANS_MESSAGES,
837 rds6_conn_message_info_retrans);
753} 838}
754 839
755/* 840/*