diff options
-rw-r--r-- | net/core/skbuff.c | 12 | ||||
-rw-r--r-- | net/packet/af_packet.c | 33 |
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 | ||
342 | static 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 | |||
342 | static void *packet_lookup_frame(struct packet_sock *po, | 373 | static 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) { |