diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2005-10-03 16:57:23 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-10-03 16:57:23 -0400 |
commit | 325ed8239309cb29f10ea58c5a668058ead11479 (patch) | |
tree | 77386825b72ac44f4f42a942ef78bd1ff924b351 /include/linux/skbuff.h | |
parent | ddea7be0ec8d1374f0b483a81566ed56ec9f3905 (diff) |
[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>
Diffstat (limited to 'include/linux/skbuff.h')
-rw-r--r-- | include/linux/skbuff.h | 12 |
1 files changed, 3 insertions, 9 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 2741c0c55e83..466c879f82b8 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -155,8 +155,6 @@ struct skb_shared_info { | |||
155 | #define SKB_DATAREF_SHIFT 16 | 155 | #define SKB_DATAREF_SHIFT 16 |
156 | #define SKB_DATAREF_MASK ((1 << SKB_DATAREF_SHIFT) - 1) | 156 | #define SKB_DATAREF_MASK ((1 << SKB_DATAREF_SHIFT) - 1) |
157 | 157 | ||
158 | extern struct timeval skb_tv_base; | ||
159 | |||
160 | struct skb_timeval { | 158 | struct skb_timeval { |
161 | u32 off_sec; | 159 | u32 off_sec; |
162 | u32 off_usec; | 160 | u32 off_usec; |
@@ -175,7 +173,7 @@ enum { | |||
175 | * @prev: Previous buffer in list | 173 | * @prev: Previous buffer in list |
176 | * @list: List we are on | 174 | * @list: List we are on |
177 | * @sk: Socket we are owned by | 175 | * @sk: Socket we are owned by |
178 | * @tstamp: Time we arrived stored as offset to skb_tv_base | 176 | * @tstamp: Time we arrived |
179 | * @dev: Device we arrived on/are leaving by | 177 | * @dev: Device we arrived on/are leaving by |
180 | * @input_dev: Device we arrived on | 178 | * @input_dev: Device we arrived on |
181 | * @h: Transport layer header | 179 | * @h: Transport layer header |
@@ -1255,10 +1253,6 @@ static inline void skb_get_timestamp(const struct sk_buff *skb, struct timeval * | |||
1255 | { | 1253 | { |
1256 | stamp->tv_sec = skb->tstamp.off_sec; | 1254 | stamp->tv_sec = skb->tstamp.off_sec; |
1257 | stamp->tv_usec = skb->tstamp.off_usec; | 1255 | stamp->tv_usec = skb->tstamp.off_usec; |
1258 | if (skb->tstamp.off_sec) { | ||
1259 | stamp->tv_sec += skb_tv_base.tv_sec; | ||
1260 | stamp->tv_usec += skb_tv_base.tv_usec; | ||
1261 | } | ||
1262 | } | 1256 | } |
1263 | 1257 | ||
1264 | /** | 1258 | /** |
@@ -1272,8 +1266,8 @@ static inline void skb_get_timestamp(const struct sk_buff *skb, struct timeval * | |||
1272 | */ | 1266 | */ |
1273 | static inline void skb_set_timestamp(struct sk_buff *skb, const struct timeval *stamp) | 1267 | static inline void skb_set_timestamp(struct sk_buff *skb, const struct timeval *stamp) |
1274 | { | 1268 | { |
1275 | skb->tstamp.off_sec = stamp->tv_sec - skb_tv_base.tv_sec; | 1269 | skb->tstamp.off_sec = stamp->tv_sec; |
1276 | skb->tstamp.off_usec = stamp->tv_usec - skb_tv_base.tv_usec; | 1270 | skb->tstamp.off_usec = stamp->tv_usec; |
1277 | } | 1271 | } |
1278 | 1272 | ||
1279 | extern void __net_timestamp(struct sk_buff *skb); | 1273 | extern void __net_timestamp(struct sk_buff *skb); |