[NET]: Fix packet timestamping.
I've found the problem in general. It affects any 64-bit architecture. The problem occurs when you change the system time. Suppose that when you boot your system clock is forward by a day. This gets recorded down in skb_tv_base. You then wind the clock back by a day. From that point onwards the offset will be negative which essentially overflows the 32-bit variables they're stored in. In fact, why don't we just store the real time stamp in those 32-bit variables? After all, we're not going to overflow for quite a while yet. When we do overflow, we'll need a better solution of course. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
ddea7be0ec
commit
325ed82393
@@ -155,8 +155,6 @@ struct skb_shared_info {
|
||||
#define SKB_DATAREF_SHIFT 16
|
||||
#define SKB_DATAREF_MASK ((1 << SKB_DATAREF_SHIFT) - 1)
|
||||
|
||||
extern struct timeval skb_tv_base;
|
||||
|
||||
struct skb_timeval {
|
||||
u32 off_sec;
|
||||
u32 off_usec;
|
||||
@@ -175,7 +173,7 @@ enum {
|
||||
* @prev: Previous buffer in list
|
||||
* @list: List we are on
|
||||
* @sk: Socket we are owned by
|
||||
* @tstamp: Time we arrived stored as offset to skb_tv_base
|
||||
* @tstamp: Time we arrived
|
||||
* @dev: Device we arrived on/are leaving by
|
||||
* @input_dev: Device we arrived on
|
||||
* @h: Transport layer header
|
||||
@@ -1255,10 +1253,6 @@ static inline void skb_get_timestamp(const struct sk_buff *skb, struct timeval *
|
||||
{
|
||||
stamp->tv_sec = skb->tstamp.off_sec;
|
||||
stamp->tv_usec = skb->tstamp.off_usec;
|
||||
if (skb->tstamp.off_sec) {
|
||||
stamp->tv_sec += skb_tv_base.tv_sec;
|
||||
stamp->tv_usec += skb_tv_base.tv_usec;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1272,8 +1266,8 @@ static inline void skb_get_timestamp(const struct sk_buff *skb, struct timeval *
|
||||
*/
|
||||
static inline void skb_set_timestamp(struct sk_buff *skb, const struct timeval *stamp)
|
||||
{
|
||||
skb->tstamp.off_sec = stamp->tv_sec - skb_tv_base.tv_sec;
|
||||
skb->tstamp.off_usec = stamp->tv_usec - skb_tv_base.tv_usec;
|
||||
skb->tstamp.off_sec = stamp->tv_sec;
|
||||
skb->tstamp.off_usec = stamp->tv_usec;
|
||||
}
|
||||
|
||||
extern void __net_timestamp(struct sk_buff *skb);
|
||||
|
Reference in New Issue
Block a user