#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
+#define HAVE_NETDEV_QUEUE_STATS
+#endif
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
#include <linux/if_tunnel.h>
spinlock_t lock;
};
+#ifdef HAVE_NETDEV_QUEUE_STATS
+#define UPDATE_TX_STATS() \
+ txq->tx_bytes += pkt_len; \
+ txq->tx_packets++;
+#else
+#define UPDATE_TX_STATS() \
+ stats->tx_bytes += pkt_len; \
+ stats->tx_packets++;
+#endif
+
#define IPTUNNEL_XMIT() do { \
int err; \
int pkt_len = skb->len - skb_transport_offset(skb); \
ip_select_ident(iph, &rt->u.dst, NULL); \
\
err = ip_local_out(skb); \
- if (net_xmit_eval(err) == 0) { \
- stats->tx_bytes += pkt_len; \
- stats->tx_packets++; \
+ if (likely(net_xmit_eval(err) == 0)) { \
+ UPDATE_TX_STATS(); \
} else { \
stats->tx_errors++; \
stats->tx_aborted_errors++; \
{
struct ip_tunnel *tunnel = netdev_priv(dev);
struct net_device_stats *stats;
+#ifdef HAVE_NETDEV_QUEUE_STATS
+ struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
+#endif
struct iphdr *old_iph = ip_hdr(skb);
struct iphdr *tiph;
u8 tos;
int mtu;
#ifdef HAVE_NETDEV_STATS
- stats = &tunnel->dev->stats;
+ stats = &dev->stats;
#else
stats = &tunnel->stat;
#endif
struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
if (!new_skb) {
ip_rt_put(rt);
+#ifdef HAVE_NETDEV_QUEUE_STATS
+ txq->tx_dropped++;
+#else
stats->tx_dropped++;
+#endif
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}