summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--quicktun.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/quicktun.c b/quicktun.c
index 44b7a7e..3ecc0cc 100644
--- a/quicktun.c
+++ b/quicktun.c
@@ -33,17 +33,18 @@ struct quicktun_struct {
};
-static void quicktun_net_uninit(struct net_device *dev)
-{
-}
-
static netdev_tx_t quicktun_net_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct quicktun_struct *tun = netdev_priv(dev);
struct msghdr msg;
struct kvec vec;
+ int err;
if (tun->remote_address.sin_addr.s_addr) {
+ err = skb_linearize(skb);
+ if (err < 0)
+ goto err;
+
vec.iov_base = skb->data;
vec.iov_len = skb->len;
@@ -59,6 +60,11 @@ static netdev_tx_t quicktun_net_xmit(struct sk_buff *skb, struct net_device *dev
consume_skb(skb);
return NETDEV_TX_OK;
+
+ err:
+ kfree_skb(skb);
+
+ return NETDEV_TX_OK;
}
static void quicktun_udp_data_ready(struct sock *sk, int bytes)
@@ -78,7 +84,11 @@ static void quicktun_udp_data_ready(struct sock *sk, int bytes)
skb_orphan(skb);
- skb_pull(skb, sizeof(struct udphdr));
+ err = skb_linearize(skb);
+ if (err < 0)
+ goto err;
+
+ __skb_pull(skb, sizeof(struct udphdr));
switch (tun->flags & QUICKTUN_MODE_MASK) {
case QUICKTUN_MODE_ETHERNET:
@@ -94,6 +104,10 @@ static void quicktun_udp_data_ready(struct sock *sk, int bytes)
}
netif_rx_ni(skb);
+ return;
+
+ err:
+ kfree_skb(skb);
}
static int
@@ -107,7 +121,6 @@ quicktun_net_change_mtu(struct net_device *dev, int new_mtu)
static const struct net_device_ops quicktun_ethernet_netdev_ops = {
- .ndo_uninit = quicktun_net_uninit,
.ndo_start_xmit = quicktun_net_xmit,
.ndo_change_mtu = quicktun_net_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
@@ -115,7 +128,6 @@ static const struct net_device_ops quicktun_ethernet_netdev_ops = {
};
static const struct net_device_ops quicktun_ip_netdev_ops = {
- .ndo_uninit = quicktun_net_uninit,
.ndo_start_xmit = quicktun_net_xmit,
.ndo_change_mtu = quicktun_net_change_mtu,
};
@@ -151,10 +163,6 @@ static const struct ethtool_ops quicktun_ethtool_ops = {
};
-static void quicktun_free_netdev(struct net_device *dev)
-{
-}
-
static void quicktun_setup(struct net_device *dev)
{
struct quicktun_struct *tun = netdev_priv(dev);
@@ -167,7 +175,6 @@ static void quicktun_setup(struct net_device *dev)
tun->remote_address.sin_port = htons(QUICKTUN_DEFAULT_PORT);
dev->ethtool_ops = &quicktun_ethtool_ops;
- dev->destructor = quicktun_free_netdev;
}
static void quicktun_net_init(struct net_device *dev)