1111#define pr_fmt (fmt ) KBUILD_MODNAME ": " fmt
1212
1313#include <linux/in.h>
14+ #include <linux/in6.h>
1415#include <linux/module.h>
1516#include <linux/net.h>
1617#include <linux/ipv6.h>
@@ -954,64 +955,55 @@ static void p9_fd_close(struct p9_client *client)
954955 kfree (ts );
955956}
956957
957- /*
958- * stolen from NFS - maybe should be made a generic function?
959- */
960- static inline int valid_ipaddr4 (const char * buf )
961- {
962- int rc , count , in [4 ];
963-
964- rc = sscanf (buf , "%d.%d.%d.%d" , & in [0 ], & in [1 ], & in [2 ], & in [3 ]);
965- if (rc != 4 )
966- return - EINVAL ;
967- for (count = 0 ; count < 4 ; count ++ ) {
968- if (in [count ] > 255 )
969- return - EINVAL ;
970- }
971- return 0 ;
972- }
973-
974958static int p9_bind_privport (struct socket * sock )
975959{
976- struct sockaddr_in cl ;
960+ struct sockaddr_storage stor = { 0 } ;
977961 int port , err = - EINVAL ;
978962
979- memset (& cl , 0 , sizeof (cl ));
980- cl .sin_family = AF_INET ;
981- cl .sin_addr .s_addr = htonl (INADDR_ANY );
963+ stor .ss_family = sock -> ops -> family ;
964+ if (stor .ss_family == AF_INET )
965+ ((struct sockaddr_in * )& stor )-> sin_addr .s_addr = htonl (INADDR_ANY );
966+ else
967+ ((struct sockaddr_in6 * )& stor )-> sin6_addr = in6addr_any ;
982968 for (port = p9_ipport_resv_max ; port >= p9_ipport_resv_min ; port -- ) {
983- cl .sin_port = htons ((ushort )port );
984- err = kernel_bind (sock , (struct sockaddr * )& cl , sizeof (cl ));
969+ if (stor .ss_family == AF_INET )
970+ ((struct sockaddr_in * )& stor )-> sin_port = htons ((ushort )port );
971+ else
972+ ((struct sockaddr_in6 * )& stor )-> sin6_port = htons ((ushort )port );
973+ err = kernel_bind (sock , (struct sockaddr * )& stor , sizeof (stor ));
985974 if (err != - EADDRINUSE )
986975 break ;
987976 }
988977 return err ;
989978}
990979
991-
992980static int
993981p9_fd_create_tcp (struct p9_client * client , const char * addr , char * args )
994982{
995983 int err ;
984+ char port_str [6 ];
996985 struct socket * csocket ;
997- struct sockaddr_in sin_server ;
986+ struct sockaddr_storage stor = { 0 } ;
998987 struct p9_fd_opts opts ;
999988
1000989 err = parse_opts (args , & opts );
1001990 if (err < 0 )
1002991 return err ;
1003992
1004- if (addr == NULL || valid_ipaddr4 ( addr ) < 0 )
993+ if (! addr )
1005994 return - EINVAL ;
1006995
996+ sprintf (port_str , "%u" , opts .port );
997+ err = inet_pton_with_scope (current -> nsproxy -> net_ns , AF_UNSPEC , addr ,
998+ port_str , & stor );
999+ if (err < 0 )
1000+ return err ;
1001+
10071002 csocket = NULL ;
10081003
10091004 client -> trans_opts .tcp .port = opts .port ;
10101005 client -> trans_opts .tcp .privport = opts .privport ;
1011- sin_server .sin_family = AF_INET ;
1012- sin_server .sin_addr .s_addr = in_aton (addr );
1013- sin_server .sin_port = htons (opts .port );
1014- err = __sock_create (current -> nsproxy -> net_ns , PF_INET ,
1006+ err = __sock_create (current -> nsproxy -> net_ns , stor .ss_family ,
10151007 SOCK_STREAM , IPPROTO_TCP , & csocket , 1 );
10161008 if (err ) {
10171009 pr_err ("%s (%d): problem creating socket\n" ,
@@ -1030,8 +1022,8 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
10301022 }
10311023
10321024 err = READ_ONCE (csocket -> ops )-> connect (csocket ,
1033- (struct sockaddr * )& sin_server ,
1034- sizeof (struct sockaddr_in ), 0 );
1025+ (struct sockaddr * )& stor ,
1026+ sizeof (stor ), 0 );
10351027 if (err < 0 ) {
10361028 pr_err ("%s (%d): problem connecting socket to %s\n" ,
10371029 __func__ , task_pid_nr (current ), addr );
0 commit comments