aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/core/skbuff.c12
-rw-r--r--net/packet/af_packet.c33
2 files changed, 39 insertions, 6 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 898cf5c566f9..af9185d0be6a 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3327,12 +3327,8 @@ void skb_tstamp_tx(struct sk_buff *orig_skb,
3327 if (!sk) 3327 if (!sk)
3328 return; 3328 return;
3329 3329
3330 skb = skb_clone(orig_skb, GFP_ATOMIC);
3331 if (!skb)
3332 return;
3333
3334 if (hwtstamps) { 3330 if (hwtstamps) {
3335 *skb_hwtstamps(skb) = 3331 *skb_hwtstamps(orig_skb) =
3336 *hwtstamps; 3332 *hwtstamps;
3337 } else { 3333 } else {
3338 /* 3334 /*
@@ -3340,9 +3336,13 @@ void skb_tstamp_tx(struct sk_buff *orig_skb,
3340 * so keep the shared tx_flags and only 3336 * so keep the shared tx_flags and only
3341 * store software time stamp 3337 * store software time stamp
3342 */ 3338 */
3343 skb->tstamp = ktime_get_real(); 3339 orig_skb->tstamp = ktime_get_real();
3344 } 3340 }
3345 3341
3342 skb = skb_clone(orig_skb, GFP_ATOMIC);
3343 if (!skb)
3344 return;
3345
3346 serr = SKB_EXT_ERR(skb); 3346 serr = SKB_EXT_ERR(skb);
3347 memset(serr, 0, sizeof(*serr)); 3347 memset(serr, 0, sizeof(*serr));
3348 serr->ee.ee_errno = ENOMSG; 3348 serr->ee.ee_errno = ENOMSG;
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 7e387ff64465..ec8ea27733ac 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -339,6 +339,37 @@ static int __packet_get_status(struct packet_sock *po, void *frame)
339 } 339 }
340} 340}
341 341
342static void __packet_set_timestamp(struct packet_sock *po, void *frame,
343 ktime_t tstamp)
344{
345 union tpacket_uhdr h;
346 struct timespec ts;
347
348 if (!ktime_to_timespec_cond(tstamp, &ts) ||
349 !sock_flag(&po->sk, SOCK_TIMESTAMPING_SOFTWARE))
350 return;
351
352 h.raw = frame;
353 switch (po->tp_version) {
354 case TPACKET_V1:
355 h.h1->tp_sec = ts.tv_sec;
356 h.h1->tp_usec = ts.tv_nsec / NSEC_PER_USEC;
357 break;
358 case TPACKET_V2:
359 h.h2->tp_sec = ts.tv_sec;
360 h.h2->tp_nsec = ts.tv_nsec;
361 break;
362 case TPACKET_V3:
363 default:
364 WARN(1, "TPACKET version not supported.\n");
365 BUG();
366 }
367
368 /* one flush is safe, as both fields always lie on the same cacheline */
369 flush_dcache_page(pgv_to_page(&h.h1->tp_sec));
370 smp_wmb();
371}
372
342static void *packet_lookup_frame(struct packet_sock *po, 373static void *packet_lookup_frame(struct packet_sock *po,
343 struct packet_ring_buffer *rb, 374 struct packet_ring_buffer *rb,
344 unsigned int position, 375 unsigned int position,
@@ -1877,6 +1908,7 @@ static void tpacket_destruct_skb(struct sk_buff *skb)
1877 ph = skb_shinfo(skb)->destructor_arg; 1908 ph = skb_shinfo(skb)->destructor_arg;
1878 BUG_ON(atomic_read(&po->tx_ring.pending) == 0); 1909 BUG_ON(atomic_read(&po->tx_ring.pending) == 0);
1879 atomic_dec(&po->tx_ring.pending); 1910 atomic_dec(&po->tx_ring.pending);
1911 __packet_set_timestamp(po, ph, skb->tstamp);
1880 __packet_set_status(po, ph, TP_STATUS_AVAILABLE); 1912 __packet_set_status(po, ph, TP_STATUS_AVAILABLE);
1881 } 1913 }
1882 1914
@@ -1900,6 +1932,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
1900 skb->dev = dev; 1932 skb->dev = dev;
1901 skb->priority = po->sk.sk_priority; 1933 skb->priority = po->sk.sk_priority;
1902 skb->mark = po->sk.sk_mark; 1934 skb->mark = po->sk.sk_mark;
1935 sock_tx_timestamp(&po->sk, &skb_shinfo(skb)->tx_flags);
1903 skb_shinfo(skb)->destructor_arg = ph.raw; 1936 skb_shinfo(skb)->destructor_arg = ph.raw;
1904 1937
1905 switch (po->tp_version) { 1938 switch (po->tp_version) {