diff options
author | Daniel Borkmann <dborkman@redhat.com> | 2013-04-15 21:29:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-19 16:39:13 -0400 |
commit | 4b457bdf1dbc961b62252034b05d47ec3e5b85d2 (patch) | |
tree | 7b01a36483600674897353035c4cb99949829e5a /net/packet | |
parent | 6e94d1ef37e439bf45659cc071553574ccb98080 (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.c | 57 |
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 | ||
1660 | static 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 | |||
1660 | static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, | 1680 | static 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); |