aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Ohly <patrick.ohly@intel.com>2009-02-12 00:03:39 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-16 01:43:38 -0500
commit51f31cabe3ce5345b51e4a4f82138b38c4d5dc91 (patch)
treef59504adbbe37e6e28ac78e6a49f045508daa78e
parent20d4947353be60e909e6b1a79d241457edd6833f (diff)
ip: support for TX timestamps on UDP and RAW sockets
Instructions for time stamping outgoing packets are take from the socket layer and later copied into the new skb. Signed-off-by: Patrick Ohly <patrick.ohly@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/networking/timestamping.txt2
-rw-r--r--include/net/ip.h1
-rw-r--r--net/can/raw.c3
-rw-r--r--net/ipv4/icmp.c2
-rw-r--r--net/ipv4/ip_output.c6
-rw-r--r--net/ipv4/raw.c1
-rw-r--r--net/ipv4/udp.c4
7 files changed, 19 insertions, 0 deletions
diff --git a/Documentation/networking/timestamping.txt b/Documentation/networking/timestamping.txt
index a681a65b5bc7..0e58b4539176 100644
--- a/Documentation/networking/timestamping.txt
+++ b/Documentation/networking/timestamping.txt
@@ -56,6 +56,8 @@ and including the link layer, the scm_timestamping control message and
56a sock_extended_err control message with ee_errno==ENOMSG and 56a sock_extended_err control message with ee_errno==ENOMSG and
57ee_origin==SO_EE_ORIGIN_TIMESTAMPING. A socket with such a pending 57ee_origin==SO_EE_ORIGIN_TIMESTAMPING. A socket with such a pending
58bounced packet is ready for reading as far as select() is concerned. 58bounced packet is ready for reading as far as select() is concerned.
59If the outgoing packet has to be fragmented, then only the first
60fragment is time stamped and returned to the sending socket.
59 61
60All three values correspond to the same event in time, but were 62All three values correspond to the same event in time, but were
61generated in different ways. Each of these values may be empty (= all 63generated in different ways. Each of these values may be empty (= all
diff --git a/include/net/ip.h b/include/net/ip.h
index 10868139e656..4ac7577f98d0 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -55,6 +55,7 @@ struct ipcm_cookie
55 __be32 addr; 55 __be32 addr;
56 int oif; 56 int oif;
57 struct ip_options *opt; 57 struct ip_options *opt;
58 union skb_shared_tx shtx;
58}; 59};
59 60
60#define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb)) 61#define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb))
diff --git a/net/can/raw.c b/net/can/raw.c
index 0703cba4bf9f..6aa154e806ae 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -648,6 +648,9 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock,
648 err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); 648 err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
649 if (err < 0) 649 if (err < 0)
650 goto free_skb; 650 goto free_skb;
651 err = sock_tx_timestamp(msg, sk, skb_tx(skb));
652 if (err < 0)
653 goto free_skb;
651 skb->dev = dev; 654 skb->dev = dev;
652 skb->sk = sk; 655 skb->sk = sk;
653 656
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 705b33b184a3..382800a62b31 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -375,6 +375,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
375 inet->tos = ip_hdr(skb)->tos; 375 inet->tos = ip_hdr(skb)->tos;
376 daddr = ipc.addr = rt->rt_src; 376 daddr = ipc.addr = rt->rt_src;
377 ipc.opt = NULL; 377 ipc.opt = NULL;
378 ipc.shtx.flags = 0;
378 if (icmp_param->replyopts.optlen) { 379 if (icmp_param->replyopts.optlen) {
379 ipc.opt = &icmp_param->replyopts; 380 ipc.opt = &icmp_param->replyopts;
380 if (ipc.opt->srr) 381 if (ipc.opt->srr)
@@ -532,6 +533,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
532 inet_sk(sk)->tos = tos; 533 inet_sk(sk)->tos = tos;
533 ipc.addr = iph->saddr; 534 ipc.addr = iph->saddr;
534 ipc.opt = &icmp_param.replyopts; 535 ipc.opt = &icmp_param.replyopts;
536 ipc.shtx.flags = 0;
535 537
536 { 538 {
537 struct flowi fl = { 539 struct flowi fl = {
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 8ebe86dd72af..3e7e910c7c0f 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -935,6 +935,10 @@ alloc_new_skb:
935 sk->sk_allocation); 935 sk->sk_allocation);
936 if (unlikely(skb == NULL)) 936 if (unlikely(skb == NULL))
937 err = -ENOBUFS; 937 err = -ENOBUFS;
938 else
939 /* only the initial fragment is
940 time stamped */
941 ipc->shtx.flags = 0;
938 } 942 }
939 if (skb == NULL) 943 if (skb == NULL)
940 goto error; 944 goto error;
@@ -945,6 +949,7 @@ alloc_new_skb:
945 skb->ip_summed = csummode; 949 skb->ip_summed = csummode;
946 skb->csum = 0; 950 skb->csum = 0;
947 skb_reserve(skb, hh_len); 951 skb_reserve(skb, hh_len);
952 *skb_tx(skb) = ipc->shtx;
948 953
949 /* 954 /*
950 * Find where to start putting bytes. 955 * Find where to start putting bytes.
@@ -1364,6 +1369,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
1364 1369
1365 daddr = ipc.addr = rt->rt_src; 1370 daddr = ipc.addr = rt->rt_src;
1366 ipc.opt = NULL; 1371 ipc.opt = NULL;
1372 ipc.shtx.flags = 0;
1367 1373
1368 if (replyopts.opt.optlen) { 1374 if (replyopts.opt.optlen) {
1369 ipc.opt = &replyopts.opt; 1375 ipc.opt = &replyopts.opt;
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index dff8bc4e0fac..f774651f0a47 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -493,6 +493,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
493 493
494 ipc.addr = inet->saddr; 494 ipc.addr = inet->saddr;
495 ipc.opt = NULL; 495 ipc.opt = NULL;
496 ipc.shtx.flags = 0;
496 ipc.oif = sk->sk_bound_dev_if; 497 ipc.oif = sk->sk_bound_dev_if;
497 498
498 if (msg->msg_controllen) { 499 if (msg->msg_controllen) {
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index c47c989cb1fb..4bd178a111d5 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -596,6 +596,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
596 return -EOPNOTSUPP; 596 return -EOPNOTSUPP;
597 597
598 ipc.opt = NULL; 598 ipc.opt = NULL;
599 ipc.shtx.flags = 0;
599 600
600 if (up->pending) { 601 if (up->pending) {
601 /* 602 /*
@@ -643,6 +644,9 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
643 ipc.addr = inet->saddr; 644 ipc.addr = inet->saddr;
644 645
645 ipc.oif = sk->sk_bound_dev_if; 646 ipc.oif = sk->sk_bound_dev_if;
647 err = sock_tx_timestamp(msg, sk, &ipc.shtx);
648 if (err)
649 return err;
646 if (msg->msg_controllen) { 650 if (msg->msg_controllen) {
647 err = ip_cmsg_send(sock_net(sk), msg, &ipc); 651 err = ip_cmsg_send(sock_net(sk), msg, &ipc);
648 if (err) 652 if (err)