Skip to content

Commit

Permalink
net-timestamp: SOCK_RAW and PING timestamping
Browse files Browse the repository at this point in the history
Add SO_TIMESTAMPING to sockets of type PF_INET[6]/SOCK_RAW:

Add the necessary sock_tx_timestamp calls to the datapath for RAW
sockets (ping sockets already had these calls).

Fix the IP output path to pass the timestamp flags on the first
fragment also for these sockets. The existing code relies on
transhdrlen != 0 to indicate a first fragment. For these sockets,
that assumption does not hold.

This fixes http://bugzilla.kernel.org/show_bug.cgi?id=77221

Tested SOCK_RAW on IPv4 and IPv6, not PING.

Signed-off-by: Willem de Bruijn <willemb@google.com>
Acked-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
wdebruij authored and davem330 committed Jul 15, 2014
1 parent d5c1c93 commit 11878b4
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 13 deletions.
7 changes: 3 additions & 4 deletions net/ipv4/ip_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -962,10 +962,6 @@ static int __ip_append_data(struct sock *sk,
sk->sk_allocation);
if (unlikely(skb == NULL))
err = -ENOBUFS;
else
/* only the initial fragment is
time stamped */
cork->tx_flags = 0;
}
if (skb == NULL)
goto error;
Expand All @@ -976,7 +972,10 @@ static int __ip_append_data(struct sock *sk,
skb->ip_summed = csummode;
skb->csum = 0;
skb_reserve(skb, hh_len);

/* only the initial fragment is time stamped */
skb_shinfo(skb)->tx_flags = cork->tx_flags;
cork->tx_flags = 0;

/*
* Find where to start putting bytes.
Expand Down
4 changes: 4 additions & 0 deletions net/ipv4/raw.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,8 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,

skb->ip_summed = CHECKSUM_NONE;

sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags);

skb->transport_header = skb->network_header;
err = -EFAULT;
if (memcpy_fromiovecend((void *)iph, from, 0, length))
Expand Down Expand Up @@ -606,6 +608,8 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
&rt, msg->msg_flags);

else {
sock_tx_timestamp(sk, &ipc.tx_flags);

if (!ipc.addr)
ipc.addr = fl4.daddr;
lock_sock(sk);
Expand Down
13 changes: 4 additions & 9 deletions net/ipv6/ip6_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -1271,7 +1271,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
}

/* For UDP, check if TX timestamp is enabled */
if (sk->sk_type == SOCK_DGRAM)
if (sk->sk_type == SOCK_DGRAM || sk->sk_type == SOCK_RAW)
sock_tx_timestamp(sk, &tx_flags);

/*
Expand Down Expand Up @@ -1380,12 +1380,6 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
sk->sk_allocation);
if (unlikely(skb == NULL))
err = -ENOBUFS;
else {
/* Only the initial fragment
* is time stamped.
*/
tx_flags = 0;
}
}
if (skb == NULL)
goto error;
Expand All @@ -1399,8 +1393,9 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
skb_reserve(skb, hh_len + sizeof(struct frag_hdr) +
dst_exthdrlen);

if (sk->sk_type == SOCK_DGRAM)
skb_shinfo(skb)->tx_flags = tx_flags;
/* Only the initial fragment is time stamped */
skb_shinfo(skb)->tx_flags = tx_flags;
tx_flags = 0;

/*
* Find where to start putting bytes
Expand Down

0 comments on commit 11878b4

Please sign in to comment.