@ -52,6 +52,7 @@
# include <net/dst.h>
# include <net/ip.h>
# include <net/udp.h>
# include <net/udp_tunnel.h>
# include <net/inet_common.h>
# include <net/xfrm.h>
# include <net/protocol.h>
@ -1358,81 +1359,46 @@ static int l2tp_tunnel_sock_create(struct net *net,
{
int err = - EINVAL ;
struct socket * sock = NULL ;
struct sockaddr_in udp_addr = { 0 } ;
struct sockaddr_l2tpip ip_addr = { 0 } ;
# if IS_ENABLED(CONFIG_IPV6)
struct sockaddr_in6 udp6_addr = { 0 } ;
struct sockaddr_l2tpip6 ip6_addr = { 0 } ;
# endif
struct udp_port_cfg udp_conf ;
switch ( cfg - > encap ) {
case L2TP_ENCAPTYPE_UDP :
memset ( & udp_conf , 0 , sizeof ( udp_conf ) ) ;
# if IS_ENABLED(CONFIG_IPV6)
if ( cfg - > local_ip6 & & cfg - > peer_ip6 ) {
err = sock_create_kern ( AF_INET6 , SOCK_DGRAM , 0 , & sock ) ;
if ( err < 0 )
goto out ;
sk_change_net ( sock - > sk , net ) ;
udp6_addr . sin6_family = AF_INET6 ;
memcpy ( & udp6_addr . sin6_addr , cfg - > local_ip6 ,
sizeof ( udp6_addr . sin6_addr ) ) ;
udp6_addr . sin6_port = htons ( cfg - > local_udp_port ) ;
err = kernel_bind ( sock , ( struct sockaddr * ) & udp6_addr ,
sizeof ( udp6_addr ) ) ;
if ( err < 0 )
goto out ;
udp6_addr . sin6_family = AF_INET6 ;
memcpy ( & udp6_addr . sin6_addr , cfg - > peer_ip6 ,
sizeof ( udp6_addr . sin6_addr ) ) ;
udp6_addr . sin6_port = htons ( cfg - > peer_udp_port ) ;
err = kernel_connect ( sock ,
( struct sockaddr * ) & udp6_addr ,
sizeof ( udp6_addr ) , 0 ) ;
if ( err < 0 )
goto out ;
if ( cfg - > udp6_zero_tx_checksums )
udp_set_no_check6_tx ( sock - > sk , true ) ;
if ( cfg - > udp6_zero_rx_checksums )
udp_set_no_check6_rx ( sock - > sk , true ) ;
udp_conf . family = AF_INET6 ;
memcpy ( & udp_conf . local_ip6 , cfg - > local_ip6 ,
sizeof ( udp_conf . local_ip6 ) ) ;
memcpy ( & udp_conf . peer_ip6 , cfg - > peer_ip6 ,
sizeof ( udp_conf . peer_ip6 ) ) ;
udp_conf . use_udp6_tx_checksums =
cfg - > udp6_zero_tx_checksums ;
udp_conf . use_udp6_rx_checksums =
cfg - > udp6_zero_rx_checksums ;
} else
# endif
{
err = sock_create_kern ( AF_INET , SOCK_DGRAM , 0 , & sock ) ;
if ( err < 0 )
goto out ;
sk_change_net ( sock - > sk , net ) ;
udp_addr . sin_family = AF_INET ;
udp_addr . sin_addr = cfg - > local_ip ;
udp_addr . sin_port = htons ( cfg - > local_udp_port ) ;
err = kernel_bind ( sock , ( struct sockaddr * ) & udp_addr ,
sizeof ( udp_addr ) ) ;
if ( err < 0 )
goto out ;
udp_addr . sin_family = AF_INET ;
udp_addr . sin_addr = cfg - > peer_ip ;
udp_addr . sin_port = htons ( cfg - > peer_udp_port ) ;
err = kernel_connect ( sock ,
( struct sockaddr * ) & udp_addr ,
sizeof ( udp_addr ) , 0 ) ;
if ( err < 0 )
goto out ;
udp_conf . family = AF_INET ;
udp_conf . local_ip = cfg - > local_ip ;
udp_conf . peer_ip = cfg - > peer_ip ;
udp_conf . use_udp_checksums = cfg - > use_udp_checksums ;
}
if ( ! cfg - > use_udp_checksums )
sock - > sk - > sk_no_check_tx = 1 ;
udp_conf . local_udp_port = htons ( cfg - > local_udp_port ) ;
udp_conf . peer_udp_port = htons ( cfg - > peer_udp_port ) ;
err = udp_sock_create ( net , & udp_conf , & sock ) ;
if ( err < 0 )
goto out ;
break ;
case L2TP_ENCAPTYPE_IP :
# if IS_ENABLED(CONFIG_IPV6)
if ( cfg - > local_ip6 & & cfg - > peer_ip6 ) {
struct sockaddr_l2tpip6 ip6_addr = { 0 } ;
err = sock_create_kern ( AF_INET6 , SOCK_DGRAM ,
IPPROTO_L2TP , & sock ) ;
if ( err < 0 )
@ -1461,6 +1427,8 @@ static int l2tp_tunnel_sock_create(struct net *net,
} else
# endif
{
struct sockaddr_l2tpip ip_addr = { 0 } ;
err = sock_create_kern ( AF_INET , SOCK_DGRAM ,
IPPROTO_L2TP , & sock ) ;
if ( err < 0 )