diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2011-04-14 03:07:33 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2011-04-14 03:07:33 +0200 |
commit | 888629be2dd5a0b7d2d6707efc8315c96dfb8867 (patch) | |
tree | 025c36d8dc37dec5d0d5390ac3256e32959b0149 | |
parent | 35bfd16af8f8316de5ee392fe06020a7d7ed7a33 (diff) | |
download | modquicktun-888629be2dd5a0b7d2d6707efc8315c96dfb8867.tar modquicktun-888629be2dd5a0b7d2d6707efc8315c96dfb8867.zip |
Make receiving work
-rw-r--r-- | quicktun.c | 37 |
1 files changed, 35 insertions, 2 deletions
@@ -1,7 +1,9 @@ #include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/if_arp.h> +#include <linux/ip.h> #include <linux/netdevice.h> +#include <linux/udp.h> #include <net/genetlink.h> #include <net/sock.h> @@ -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; |