From 0ad97454e708a7f0ca0db36c2b90d1ae6c74ae30 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 15 Apr 2011 04:13:32 +0200 Subject: Update packet, byte and drop stats. --- quicktun.c | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/quicktun.c b/quicktun.c index 3ecc0cc..6899a05 100644 --- a/quicktun.c +++ b/quicktun.c @@ -43,7 +43,7 @@ static netdev_tx_t quicktun_net_xmit(struct sk_buff *skb, struct net_device *dev if (tun->remote_address.sin_addr.s_addr) { err = skb_linearize(skb); if (err < 0) - goto err; + goto drop; vec.iov_base = skb->data; vec.iov_len = skb->len; @@ -55,24 +55,31 @@ static netdev_tx_t quicktun_net_xmit(struct sk_buff *skb, struct net_device *dev msg.msg_flags = MSG_DONTWAIT; kernel_sendmsg(tun->sock, &msg, &vec, 1, skb->len); + + tun->dev->stats.tx_packets++; + tun->dev->stats.tx_bytes += skb->len; } + else + goto drop; consume_skb(skb); return NETDEV_TX_OK; - err: + drop: kfree_skb(skb); + tun->dev->stats.tx_dropped++; return NETDEV_TX_OK; } static void quicktun_udp_data_ready(struct sock *sk, int bytes) { - int err; struct sk_buff *skb; + unsigned int len; struct quicktun_struct *tun = sk->sk_user_data; - struct iphdr *iphdr; + int err; + skb = skb_recv_datagram(sk, 0, 1, &err); if (!skb) { @@ -86,27 +93,45 @@ static void quicktun_udp_data_ready(struct sock *sk, int bytes) err = skb_linearize(skb); if (err < 0) - goto err; + goto drop; __skb_pull(skb, sizeof(struct udphdr)); + len = skb->len; + switch (tun->flags & QUICKTUN_MODE_MASK) { case QUICKTUN_MODE_ETHERNET: skb->protocol = eth_type_trans(skb, tun->dev); break; + case QUICKTUN_MODE_IP: __skb_tunnel_rx(skb, tun->dev); skb_reset_network_header(skb); - iphdr = (struct iphdr*)skb->data; - skb->protocol = htons((iphdr->version == 6) ? ETH_P_IPV6 : ETH_P_IP); + switch (skb->data[0] & 0xf0) { + case 0x40: + skb->protocol = htons(ETH_P_IP); + break; + case 0x60: + skb->protocol = htons(ETH_P_IPV6); + break; + default: + goto drop; + } break; + + default: + goto drop; } netif_rx_ni(skb); + + tun->dev->stats.rx_packets++; + tun->dev->stats.rx_bytes += len; return; - err: + drop: + tun->dev->stats.rx_dropped++; kfree_skb(skb); } -- cgit v1.2.3