summaryrefslogtreecommitdiffstats
path: root/net/packet
diff options
context:
space:
mode:
authorSoheil Hassas Yeganeh <soheil@google.com>2016-04-02 23:08:12 -0400
committerDavid S. Miller <davem@davemloft.net>2016-04-04 15:50:30 -0400
commitc14ac9451c34832554db33386a4393be8bba3a7b (patch)
tree99f4d7c46d01732fcbfdf8de89e1d9846d56c3b3 /net/packet
parentad1e46a837163a3e7160a1250825bcfafd2e714b (diff)
sock: enable timestamping using control messages
Currently, SOL_TIMESTAMPING can only be enabled using setsockopt. This is very costly when users want to sample writes to gather tx timestamps. Add support for enabling SO_TIMESTAMPING via control messages by using tsflags added in `struct sockcm_cookie` (added in the previous patches in this series) to set the tx_flags of the last skb created in a sendmsg. With this patch, the timestamp recording bits in tx_flags of the skbuff is overridden if SO_TIMESTAMPING is passed in a cmsg. Please note that this is only effective for overriding the recording timestamps flags. Users should enable timestamp reporting (e.g., SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_OPT_ID) using socket options and then should ask for SOF_TIMESTAMPING_TX_* using control messages per sendmsg to sample timestamps for each write. Signed-off-by: Soheil Hassas Yeganeh <soheil@google.com> Acked-by: Willem de Bruijn <willemb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/packet')
-rw-r--r--net/packet/af_packet.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 1ecfa710ca98..0007e23202e4 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1837,6 +1837,7 @@ static int packet_sendmsg_spkt(struct socket *sock, struct msghdr *msg,
1837 DECLARE_SOCKADDR(struct sockaddr_pkt *, saddr, msg->msg_name); 1837 DECLARE_SOCKADDR(struct sockaddr_pkt *, saddr, msg->msg_name);
1838 struct sk_buff *skb = NULL; 1838 struct sk_buff *skb = NULL;
1839 struct net_device *dev; 1839 struct net_device *dev;
1840 struct sockcm_cookie sockc;
1840 __be16 proto = 0; 1841 __be16 proto = 0;
1841 int err; 1842 int err;
1842 int extra_len = 0; 1843 int extra_len = 0;
@@ -1925,12 +1926,21 @@ retry:
1925 goto out_unlock; 1926 goto out_unlock;
1926 } 1927 }
1927 1928
1929 sockc.tsflags = 0;
1930 if (msg->msg_controllen) {
1931 err = sock_cmsg_send(sk, msg, &sockc);
1932 if (unlikely(err)) {
1933 err = -EINVAL;
1934 goto out_unlock;
1935 }
1936 }
1937
1928 skb->protocol = proto; 1938 skb->protocol = proto;
1929 skb->dev = dev; 1939 skb->dev = dev;
1930 skb->priority = sk->sk_priority; 1940 skb->priority = sk->sk_priority;
1931 skb->mark = sk->sk_mark; 1941 skb->mark = sk->sk_mark;
1932 1942
1933 sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); 1943 sock_tx_timestamp(sk, sockc.tsflags, &skb_shinfo(skb)->tx_flags);
1934 1944
1935 if (unlikely(extra_len == 4)) 1945 if (unlikely(extra_len == 4))
1936 skb->no_fcs = 1; 1946 skb->no_fcs = 1;
@@ -2486,7 +2496,8 @@ static int packet_snd_vnet_gso(struct sk_buff *skb,
2486 2496
2487static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, 2497static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
2488 void *frame, struct net_device *dev, void *data, int tp_len, 2498 void *frame, struct net_device *dev, void *data, int tp_len,
2489 __be16 proto, unsigned char *addr, int hlen, int copylen) 2499 __be16 proto, unsigned char *addr, int hlen, int copylen,
2500 const struct sockcm_cookie *sockc)
2490{ 2501{
2491 union tpacket_uhdr ph; 2502 union tpacket_uhdr ph;
2492 int to_write, offset, len, nr_frags, len_max; 2503 int to_write, offset, len, nr_frags, len_max;
@@ -2500,7 +2511,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
2500 skb->dev = dev; 2511 skb->dev = dev;
2501 skb->priority = po->sk.sk_priority; 2512 skb->priority = po->sk.sk_priority;
2502 skb->mark = po->sk.sk_mark; 2513 skb->mark = po->sk.sk_mark;
2503 sock_tx_timestamp(&po->sk, &skb_shinfo(skb)->tx_flags); 2514 sock_tx_timestamp(&po->sk, sockc->tsflags, &skb_shinfo(skb)->tx_flags);
2504 skb_shinfo(skb)->destructor_arg = ph.raw; 2515 skb_shinfo(skb)->destructor_arg = ph.raw;
2505 2516
2506 skb_reserve(skb, hlen); 2517 skb_reserve(skb, hlen);
@@ -2624,6 +2635,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2624 struct sk_buff *skb; 2635 struct sk_buff *skb;
2625 struct net_device *dev; 2636 struct net_device *dev;
2626 struct virtio_net_hdr *vnet_hdr = NULL; 2637 struct virtio_net_hdr *vnet_hdr = NULL;
2638 struct sockcm_cookie sockc;
2627 __be16 proto; 2639 __be16 proto;
2628 int err, reserve = 0; 2640 int err, reserve = 0;
2629 void *ph; 2641 void *ph;
@@ -2655,6 +2667,13 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2655 dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); 2667 dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex);
2656 } 2668 }
2657 2669
2670 sockc.tsflags = 0;
2671 if (msg->msg_controllen) {
2672 err = sock_cmsg_send(&po->sk, msg, &sockc);
2673 if (unlikely(err))
2674 goto out;
2675 }
2676
2658 err = -ENXIO; 2677 err = -ENXIO;
2659 if (unlikely(dev == NULL)) 2678 if (unlikely(dev == NULL))
2660 goto out; 2679 goto out;
@@ -2712,7 +2731,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2712 goto out_status; 2731 goto out_status;
2713 } 2732 }
2714 tp_len = tpacket_fill_skb(po, skb, ph, dev, data, tp_len, proto, 2733 tp_len = tpacket_fill_skb(po, skb, ph, dev, data, tp_len, proto,
2715 addr, hlen, copylen); 2734 addr, hlen, copylen, &sockc);
2716 if (likely(tp_len >= 0) && 2735 if (likely(tp_len >= 0) &&
2717 tp_len > dev->mtu + reserve && 2736 tp_len > dev->mtu + reserve &&
2718 !po->has_vnet_hdr && 2737 !po->has_vnet_hdr &&
@@ -2851,6 +2870,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
2851 if (unlikely(!(dev->flags & IFF_UP))) 2870 if (unlikely(!(dev->flags & IFF_UP)))
2852 goto out_unlock; 2871 goto out_unlock;
2853 2872
2873 sockc.tsflags = 0;
2854 sockc.mark = sk->sk_mark; 2874 sockc.mark = sk->sk_mark;
2855 if (msg->msg_controllen) { 2875 if (msg->msg_controllen) {
2856 err = sock_cmsg_send(sk, msg, &sockc); 2876 err = sock_cmsg_send(sk, msg, &sockc);
@@ -2908,7 +2928,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
2908 goto out_free; 2928 goto out_free;
2909 } 2929 }
2910 2930
2911 sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); 2931 sock_tx_timestamp(sk, sockc.tsflags, &skb_shinfo(skb)->tx_flags);
2912 2932
2913 if (!vnet_hdr.gso_type && (len > dev->mtu + reserve + extra_len) && 2933 if (!vnet_hdr.gso_type && (len > dev->mtu + reserve + extra_len) &&
2914 !packet_extra_vlan_len_allowed(dev, skb)) { 2934 !packet_extra_vlan_len_allowed(dev, skb)) {