From 888629be2dd5a0b7d2d6707efc8315c96dfb8867 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 14 Apr 2011 03:07:33 +0200 Subject: Make receiving work --- quicktun.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/quicktun.c b/quicktun.c index 9d1f722..e745eb1 100644 --- a/quicktun.c +++ b/quicktun.c @@ -1,7 +1,9 @@ #include #include #include +#include #include +#include #include #include @@ -12,8 +14,6 @@ #define DRV_VERSION "0.1" #define DRV_DESCRIPTION "Quicktun tunnel driver" -#define QUICKTUN_READQ_SIZE 500 - #define QUICKTUN_TYPE_MASK 0x000f #define QUICKTUN_FLAG_REMOTE_FLOAT 0x0010 @@ -55,9 +55,32 @@ static netdev_tx_t quicktun_net_xmit(struct sk_buff *skb, struct net_device *dev kernel_sendmsg(tun->sock, &msg, &vec, 1, skb->len); } + consume_skb(skb); + return NETDEV_TX_OK; } +static void quicktun_udp_data_ready(struct sock *sk, int bytes) +{ + int err; + struct sk_buff *skb; + struct quicktun_struct *tun = sk->sk_user_data; + + skb = skb_recv_datagram(sk, 0, 1, &err); + if (!skb) { + if (err == -EAGAIN) + return; + pr_info("Quicktun: UDP socket error %d", err); + return; + } + + skb_orphan(skb); + + skb_pull(skb, sizeof(struct udphdr)); + skb->protocol = eth_type_trans(skb, tun->dev); + netif_rx_ni(skb); +} + static int quicktun_net_change_mtu(struct net_device *dev, int new_mtu) { @@ -168,6 +191,9 @@ static int quicktun_socket_init(struct net_device *dev) if (err < 0) return err; + tun->sock->sk->sk_data_ready = quicktun_udp_data_ready; + tun->sock->sk->sk_user_data = tun; + err = kernel_bind(tun->sock, (struct sockaddr*)&tun->local_address, sizeof(tun->local_address)); if (err < 0) goto error; @@ -243,6 +269,8 @@ static int quicktun_cmd_create_device(struct sk_buff *skb, struct genl_info *inf if (err < 0) goto err_free_dev; + rtnl_lock(); + if (strchr(dev->name, '%')) { err = dev_alloc_name(dev, dev->name); if (err < 0) @@ -253,9 +281,14 @@ static int quicktun_cmd_create_device(struct sk_buff *skb, struct genl_info *inf if (err < 0) goto err_free_sk; + rtnl_unlock(); + return 0; err_free_sk: + rtnl_unlock(); + sock_release(tun->sock); + err_free_dev: free_netdev(dev); return err; -- cgit v1.2.3