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 | |
| 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')
| -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); |
