diff options
-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; |