From 5287546c13297060a107e08d840d93732740a2b8 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 15 Apr 2011 03:22:28 +0200 Subject: Linearize nonlinear sk_buffs --- quicktun.c | 31 +++++++++++++++++++------------ 1 file 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; @@ -58,6 +59,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; } @@ -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) -- cgit v1.2.3