aboutsummaryrefslogtreecommitdiffstats
path: root/net/packet
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2013-04-15 21:29:11 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-19 16:39:13 -0400
commit4b457bdf1dbc961b62252034b05d47ec3e5b85d2 (patch)
tree7b01a36483600674897353035c4cb99949829e5a /net/packet
parent6e94d1ef37e439bf45659cc071553574ccb98080 (diff)
packet: move hw/sw timestamp extraction into a small helper
This patch introduces a small, internal helper function, that is used by PF_PACKET. Based on the flags that are passed, it extracts the packet timestamp in the receive path. This is merely a refactoring to remove some duplicate code in tpacket_rcv(), to make it more readable, and to enable others to use this function in PF_PACKET as well, e.g. for TX. Signed-off-by: Daniel Borkmann <dborkman@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/packet')
-rw-r--r--net/packet/af_packet.c57
1 files changed, 23 insertions, 34 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index e566b793f07c..7e387ff64465 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1657,6 +1657,26 @@ drop:
1657 return 0; 1657 return 0;
1658} 1658}
1659 1659
1660static void tpacket_get_timestamp(struct sk_buff *skb, struct timespec *ts,
1661 unsigned int flags)
1662{
1663 struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
1664
1665 if (shhwtstamps) {
1666 if ((flags & SOF_TIMESTAMPING_SYS_HARDWARE) &&
1667 ktime_to_timespec_cond(shhwtstamps->syststamp, ts))
1668 return;
1669 if ((flags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
1670 ktime_to_timespec_cond(shhwtstamps->hwtstamp, ts))
1671 return;
1672 }
1673
1674 if (ktime_to_timespec_cond(skb->tstamp, ts))
1675 return;
1676
1677 getnstimeofday(ts);
1678}
1679
1660static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, 1680static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
1661 struct packet_type *pt, struct net_device *orig_dev) 1681 struct packet_type *pt, struct net_device *orig_dev)
1662{ 1682{
@@ -1670,9 +1690,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
1670 unsigned long status = TP_STATUS_USER; 1690 unsigned long status = TP_STATUS_USER;
1671 unsigned short macoff, netoff, hdrlen; 1691 unsigned short macoff, netoff, hdrlen;
1672 struct sk_buff *copy_skb = NULL; 1692 struct sk_buff *copy_skb = NULL;
1673 struct timeval tv;
1674 struct timespec ts; 1693 struct timespec ts;
1675 struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
1676 1694
1677 if (skb->pkt_type == PACKET_LOOPBACK) 1695 if (skb->pkt_type == PACKET_LOOPBACK)
1678 goto drop; 1696 goto drop;
@@ -1755,6 +1773,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
1755 spin_unlock(&sk->sk_receive_queue.lock); 1773 spin_unlock(&sk->sk_receive_queue.lock);
1756 1774
1757 skb_copy_bits(skb, 0, h.raw + macoff, snaplen); 1775 skb_copy_bits(skb, 0, h.raw + macoff, snaplen);
1776 tpacket_get_timestamp(skb, &ts, po->tp_tstamp);
1758 1777
1759 switch (po->tp_version) { 1778 switch (po->tp_version) {
1760 case TPACKET_V1: 1779 case TPACKET_V1:
@@ -1762,18 +1781,8 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
1762 h.h1->tp_snaplen = snaplen; 1781 h.h1->tp_snaplen = snaplen;
1763 h.h1->tp_mac = macoff; 1782 h.h1->tp_mac = macoff;
1764 h.h1->tp_net = netoff; 1783 h.h1->tp_net = netoff;
1765 if ((po->tp_tstamp & SOF_TIMESTAMPING_SYS_HARDWARE) 1784 h.h1->tp_sec = ts.tv_sec;
1766 && shhwtstamps->syststamp.tv64) 1785 h.h1->tp_usec = ts.tv_nsec / NSEC_PER_USEC;
1767 tv = ktime_to_timeval(shhwtstamps->syststamp);
1768 else if ((po->tp_tstamp & SOF_TIMESTAMPING_RAW_HARDWARE)
1769 && shhwtstamps->hwtstamp.tv64)
1770 tv = ktime_to_timeval(shhwtstamps->hwtstamp);
1771 else if (skb->tstamp.tv64)
1772 tv = ktime_to_timeval(skb->tstamp);
1773 else
1774 do_gettimeofday(&tv);
1775 h.h1->tp_sec = tv.tv_sec;
1776 h.h1->tp_usec = tv.tv_usec;
1777 hdrlen = sizeof(*h.h1); 1786 hdrlen = sizeof(*h.h1);
1778 break; 1787 break;
1779 case TPACKET_V2: 1788 case TPACKET_V2:
@@ -1781,16 +1790,6 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
1781 h.h2->tp_snaplen = snaplen; 1790 h.h2->tp_snaplen = snaplen;
1782 h.h2->tp_mac = macoff; 1791 h.h2->tp_mac = macoff;
1783 h.h2->tp_net = netoff; 1792 h.h2->tp_net = netoff;
1784 if ((po->tp_tstamp & SOF_TIMESTAMPING_SYS_HARDWARE)
1785 && shhwtstamps->syststamp.tv64)
1786 ts = ktime_to_timespec(shhwtstamps->syststamp);
1787 else if ((po->tp_tstamp & SOF_TIMESTAMPING_RAW_HARDWARE)
1788 && shhwtstamps->hwtstamp.tv64)
1789 ts = ktime_to_timespec(shhwtstamps->hwtstamp);
1790 else if (skb->tstamp.tv64)
1791 ts = ktime_to_timespec(skb->tstamp);
1792 else
1793 getnstimeofday(&ts);
1794 h.h2->tp_sec = ts.tv_sec; 1793 h.h2->tp_sec = ts.tv_sec;
1795 h.h2->tp_nsec = ts.tv_nsec; 1794 h.h2->tp_nsec = ts.tv_nsec;
1796 if (vlan_tx_tag_present(skb)) { 1795 if (vlan_tx_tag_present(skb)) {
@@ -1811,16 +1810,6 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
1811 h.h3->tp_snaplen = snaplen; 1810 h.h3->tp_snaplen = snaplen;
1812 h.h3->tp_mac = macoff; 1811 h.h3->tp_mac = macoff;
1813 h.h3->tp_net = netoff; 1812 h.h3->tp_net = netoff;
1814 if ((po->tp_tstamp & SOF_TIMESTAMPING_SYS_HARDWARE)
1815 && shhwtstamps->syststamp.tv64)
1816 ts = ktime_to_timespec(shhwtstamps->syststamp);
1817 else if ((po->tp_tstamp & SOF_TIMESTAMPING_RAW_HARDWARE)
1818 && shhwtstamps->hwtstamp.tv64)
1819 ts = ktime_to_timespec(shhwtstamps->hwtstamp);
1820 else if (skb->tstamp.tv64)
1821 ts = ktime_to_timespec(skb->tstamp);
1822 else
1823 getnstimeofday(&ts);
1824 h.h3->tp_sec = ts.tv_sec; 1813 h.h3->tp_sec = ts.tv_sec;
1825 h.h3->tp_nsec = ts.tv_nsec; 1814 h.h3->tp_nsec = ts.tv_nsec;
1826 hdrlen = sizeof(*h.h3); 1815 hdrlen = sizeof(*h.h3);