aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/phy.h2
-rw-r--r--include/linux/skbuff.h7
-rw-r--r--net/core/timestamping.c12
3 files changed, 17 insertions, 4 deletions
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 54fc4138955f..79f337c47388 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -420,7 +420,7 @@ struct phy_driver {
420 420
421 /* 421 /*
422 * Requests a Tx timestamp for 'skb'. The phy driver promises 422 * Requests a Tx timestamp for 'skb'. The phy driver promises
423 * to deliver it to the socket's error queue as soon as a 423 * to deliver it using skb_complete_tx_timestamp() as soon as a
424 * timestamp becomes available. One of the PTP_CLASS_ values 424 * timestamp becomes available. One of the PTP_CLASS_ values
425 * is passed in 'type'. 425 * is passed in 'type'.
426 */ 426 */
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 8bd383caa363..0f966460a345 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2020,8 +2020,13 @@ static inline bool skb_defer_rx_timestamp(struct sk_buff *skb)
2020/** 2020/**
2021 * skb_complete_tx_timestamp() - deliver cloned skb with tx timestamps 2021 * skb_complete_tx_timestamp() - deliver cloned skb with tx timestamps
2022 * 2022 *
2023 * PHY drivers may accept clones of transmitted packets for
2024 * timestamping via their phy_driver.txtstamp method. These drivers
2025 * must call this function to return the skb back to the stack, with
2026 * or without a timestamp.
2027 *
2023 * @skb: clone of the the original outgoing packet 2028 * @skb: clone of the the original outgoing packet
2024 * @hwtstamps: hardware time stamps 2029 * @hwtstamps: hardware time stamps, may be NULL if not available
2025 * 2030 *
2026 */ 2031 */
2027void skb_complete_tx_timestamp(struct sk_buff *skb, 2032void skb_complete_tx_timestamp(struct sk_buff *skb,
diff --git a/net/core/timestamping.c b/net/core/timestamping.c
index 98a52640e7cd..82fb28857b64 100644
--- a/net/core/timestamping.c
+++ b/net/core/timestamping.c
@@ -57,9 +57,13 @@ void skb_clone_tx_timestamp(struct sk_buff *skb)
57 case PTP_CLASS_V2_VLAN: 57 case PTP_CLASS_V2_VLAN:
58 phydev = skb->dev->phydev; 58 phydev = skb->dev->phydev;
59 if (likely(phydev->drv->txtstamp)) { 59 if (likely(phydev->drv->txtstamp)) {
60 if (!atomic_inc_not_zero(&sk->sk_refcnt))
61 return;
60 clone = skb_clone(skb, GFP_ATOMIC); 62 clone = skb_clone(skb, GFP_ATOMIC);
61 if (!clone) 63 if (!clone) {
64 sock_put(sk);
62 return; 65 return;
66 }
63 clone->sk = sk; 67 clone->sk = sk;
64 phydev->drv->txtstamp(phydev, clone, type); 68 phydev->drv->txtstamp(phydev, clone, type);
65 } 69 }
@@ -77,8 +81,11 @@ void skb_complete_tx_timestamp(struct sk_buff *skb,
77 struct sock_exterr_skb *serr; 81 struct sock_exterr_skb *serr;
78 int err; 82 int err;
79 83
80 if (!hwtstamps) 84 if (!hwtstamps) {
85 sock_put(sk);
86 kfree_skb(skb);
81 return; 87 return;
88 }
82 89
83 *skb_hwtstamps(skb) = *hwtstamps; 90 *skb_hwtstamps(skb) = *hwtstamps;
84 serr = SKB_EXT_ERR(skb); 91 serr = SKB_EXT_ERR(skb);
@@ -87,6 +94,7 @@ void skb_complete_tx_timestamp(struct sk_buff *skb,
87 serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; 94 serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING;
88 skb->sk = NULL; 95 skb->sk = NULL;
89 err = sock_queue_err_skb(sk, skb); 96 err = sock_queue_err_skb(sk, skb);
97 sock_put(sk);
90 if (err) 98 if (err)
91 kfree_skb(skb); 99 kfree_skb(skb);
92} 100}