11
11
#define pr_fmt (fmt ) KBUILD_MODNAME ": " fmt
12
12
13
13
#include <linux/in.h>
14
+ #include <linux/in6.h>
14
15
#include <linux/module.h>
15
16
#include <linux/net.h>
16
17
#include <linux/ipv6.h>
@@ -954,64 +955,55 @@ static void p9_fd_close(struct p9_client *client)
954
955
kfree (ts );
955
956
}
956
957
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
-
974
958
static int p9_bind_privport (struct socket * sock )
975
959
{
976
- struct sockaddr_in cl ;
960
+ struct sockaddr_storage stor = { 0 } ;
977
961
int port , err = - EINVAL ;
978
962
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 ;
982
968
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 ));
985
974
if (err != - EADDRINUSE )
986
975
break ;
987
976
}
988
977
return err ;
989
978
}
990
979
991
-
992
980
static int
993
981
p9_fd_create_tcp (struct p9_client * client , const char * addr , char * args )
994
982
{
995
983
int err ;
984
+ char port_str [6 ];
996
985
struct socket * csocket ;
997
- struct sockaddr_in sin_server ;
986
+ struct sockaddr_storage stor = { 0 } ;
998
987
struct p9_fd_opts opts ;
999
988
1000
989
err = parse_opts (args , & opts );
1001
990
if (err < 0 )
1002
991
return err ;
1003
992
1004
- if (addr == NULL || valid_ipaddr4 ( addr ) < 0 )
993
+ if (! addr )
1005
994
return - EINVAL ;
1006
995
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
+
1007
1002
csocket = NULL ;
1008
1003
1009
1004
client -> trans_opts .tcp .port = opts .port ;
1010
1005
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 ,
1015
1007
SOCK_STREAM , IPPROTO_TCP , & csocket , 1 );
1016
1008
if (err ) {
1017
1009
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)
1030
1022
}
1031
1023
1032
1024
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 );
1035
1027
if (err < 0 ) {
1036
1028
pr_err ("%s (%d): problem connecting socket to %s\n" ,
1037
1029
__func__ , task_pid_nr (current ), addr );
0 commit comments