summaryrefslogtreecommitdiffstats
path: root/quicktun.c
diff options
context:
space:
mode:
Diffstat (limited to 'quicktun.c')
-rw-r--r--quicktun.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/quicktun.c b/quicktun.c
index 1c8a302..24a0d73 100644
--- a/quicktun.c
+++ b/quicktun.c
@@ -81,7 +81,7 @@ static netdev_tx_t quicktun_net_xmit(struct sk_buff *skb, struct net_device *dev
remote_addr = rcu_dereference(tun->remote_address);
- if (likely(remote_addr->addr.sin_addr.s_addr)) {
+ if (likely(remote_addr->addr.sin_addr.s_addr && remote_addr->addr.sin_port)) {
rt = ip_route_output_ports(dev_net(dev), NULL, remote_addr->addr.sin_addr.s_addr, tun->local_address.sin_addr.s_addr,
remote_addr->addr.sin_port, tun->local_address.sin_port, IPPROTO_UDP, 0, 0);
if (!rt) {
@@ -354,7 +354,7 @@ static void quicktun_setup(struct net_device *dev)
tun->local_address.sin_family = AF_INET;
tun->local_address.sin_addr.s_addr = 0;
- tun->local_address.sin_port = htons(QUICKTUN_DEFAULT_PORT);
+ tun->local_address.sin_port = 0;
dev->ethtool_ops = &quicktun_ethtool_ops;
}
@@ -393,7 +393,7 @@ static int quicktun_socket_init(struct net_device *dev)
{
int err;
struct quicktun_struct *tun = netdev_priv(dev);
-
+ int addrlen;
err = sock_create_kern(AF_INET, SOCK_DGRAM, 0, &tun->sock);
if (err < 0)
@@ -406,6 +406,11 @@ static int quicktun_socket_init(struct net_device *dev)
if (err < 0)
goto error;
+ addrlen = sizeof(tun->local_address);
+ err = kernel_getsockname(tun->sock, (struct sockaddr*)&tun->local_address, &addrlen);
+ if (err < 0)
+ goto error;
+
return 0;
error:
sock_release(tun->sock);
@@ -424,7 +429,7 @@ static struct genl_family quicktun_nl_family = {
static int quicktun_cmd_create_device(struct sk_buff *skb, struct genl_info *info)
{
- __u16 type = 0;
+ __u16 type;
struct quicktun_struct *tun;
struct net *net = genl_info_net(info);
struct net_device *dev;
@@ -434,9 +439,10 @@ static int quicktun_cmd_create_device(struct sk_buff *skb, struct genl_info *inf
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- if (info->attrs[QUICKTUN_A_MODE])
- type = nla_get_u16(info->attrs[QUICKTUN_A_MODE]);
+ if (!info->attrs[QUICKTUN_A_MODE])
+ return -EINVAL;
+ type = nla_get_u16(info->attrs[QUICKTUN_A_MODE]);
if (type != QUICKTUN_MODE_ETHERNET && type != QUICKTUN_MODE_IP)
return -EINVAL;
@@ -462,16 +468,15 @@ static int quicktun_cmd_create_device(struct sk_buff *skb, struct genl_info *inf
tun->remote_address->addr.sin_family = AF_INET;
tun->remote_address->addr.sin_addr.s_addr = 0;
- tun->remote_address->addr.sin_port = htons(QUICKTUN_DEFAULT_PORT);
+ tun->remote_address->addr.sin_port = 0;
quicktun_net_init(dev);
if (info->attrs[QUICKTUN_A_LOCAL_ADDRESS])
tun->local_address.sin_addr.s_addr = nla_get_be32(info->attrs[QUICKTUN_A_LOCAL_ADDRESS]);
- /* Set remote port to local port by default */
if (info->attrs[QUICKTUN_A_LOCAL_PORT])
- tun->remote_address->addr.sin_port = tun->local_address.sin_port = nla_get_be16(info->attrs[QUICKTUN_A_LOCAL_PORT]);
+ tun->local_address.sin_port = nla_get_be16(info->attrs[QUICKTUN_A_LOCAL_PORT]);
if (info->attrs[QUICKTUN_A_REMOTE_ADDRESS])
tun->remote_address->addr.sin_addr.s_addr = nla_get_be32(info->attrs[QUICKTUN_A_REMOTE_ADDRESS]);