diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2011-04-15 03:22:28 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2011-04-15 03:22:28 +0200 |
commit | 5287546c13297060a107e08d840d93732740a2b8 (patch) | |
tree | af5178fb9e87672f4a2666b7e5888975482193eb | |
parent | 0b8e84d2d24653d51847d1d6b4a206976f64b4f1 (diff) | |
download | modquicktun-5287546c13297060a107e08d840d93732740a2b8.tar modquicktun-5287546c13297060a107e08d840d93732740a2b8.zip |
Linearize nonlinear sk_buffs
-rw-r--r-- | quicktun.c | 31 |
1 files changed, 19 insertions, 12 deletions
@@ -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) |