Bugzilla – Bug 1536
dce-ping scenario misbehave using kernel stack
Last modified: 2013-03-12 12:53:14 EDT
To reproduce use : build/myscripts/ping/bin/dce-ping --kernel=1 then you can notice 2 problems: 1. the script scratch near end (but ping occurs well) 2. we can see a suspicious message in ping stdout : Warning: time of day goes back (-1262303999994705us), taking countermeasures. and that whatever the kernel version.
Created attachment 1524 [details] patch for ns-3-linux-3
The cause of this bug is that the clock date of the kernel is not the same that the NS3/DCE and when ping ask for time of the received packet this time is bad according to NS3 one. The solution is to add the TimeBase to kernel clock time. I propose a first patch which will not modify the api between DCE and kernel, so this first patch will not pertubate other version of kernels. In order to use retrieve the value of TimeBase from DCE I use the method named current_ns but passing a null kernel pointeur in this case DCE return the TimeBase in place of the current time. Eventually it will be better to add a dedicated method in SimImported struct named dce_timebase_ns for example and change all the 3 versions of the kernels available.
Today bugzilla refuse my second patch ? I put it below it is for DCE. diff -r 0fbedfcfd747 model/linux-socket-fd-factory.cc --- a/model/linux-socket-fd-factory.cc Fri Mar 01 14:21:32 2013 +0100 +++ b/model/linux-socket-fd-factory.cc Tue Mar 05 14:17:00 2013 +0100 @@ -213,6 +213,10 @@ } static __u64 CurrentNs (struct SimKernel *kernel) { + if (!kernel) + { + return TimeBase () * 1000000000ULL; + } return Simulator::Now ().GetNanoSeconds (); } diff -r 0fbedfcfd747 model/utils.cc --- a/model/utils.cc Fri Mar 01 14:21:32 2013 +0100 +++ b/model/utils.cc Tue Mar 05 14:17:00 2013 +0100 @@ -139,7 +139,7 @@ tv.tv_nsec = n % 1000000000; return tv; } -static unsigned long TimeBase (void) +unsigned long TimeBase (void) { // unsigned long secondsSinceEpochOnFridayApril042008 = 1207284276; // return secondsSinceEpochOnFridayApril042008; diff -r 0fbedfcfd747 model/utils.h --- a/model/utils.h Fri Mar 01 14:21:32 2013 +0100 +++ b/model/utils.h Tue Mar 05 14:17:00 2013 +0100 @@ -37,6 +37,7 @@ std::string UtilsGetAbsRealFilePath (uint32_t node, std::string path); std::string UtilsGetVirtualFilePath (std::string path); uint32_t UtilsGetNodeId (void); +unsigned long TimeBase (void); Thread * Current (void); bool HasPendingSignal (void); Time UtilsTimeToSimulationTime (Time time);
I can understand disagreement between dce and kernel clock. (In reply to comment #3) > static __u64 CurrentNs (struct SimKernel *kernel) > { > + if (!kernel) > + { > + return TimeBase () * 1000000000ULL; > + } > return Simulator::Now ().GetNanoSeconds (); > } Q1) What is the exact case of "(kernel == NULL)" ? Q2) in case of !kernel, does "CurrentNs" return fixed value ? doesn't it mean that the clock won't advance during simulation ?
(In reply to comment #4) > I can understand disagreement between dce and kernel clock. > > (In reply to comment #3) > > static __u64 CurrentNs (struct SimKernel *kernel) > > { > > + if (!kernel) > > + { > > + return TimeBase () * 1000000000ULL; > > + } > > return Simulator::Now ().GetNanoSeconds (); > > } > > Q1) What is the exact case of "(kernel == NULL)" ? I have not put any comment because it is only a temporary workaround, because I do not want to start adding a new method in SimImported structure in order to preserve the good working of all the available version of kernels for DCE. So I add a new usage the the function currentNS ie : we called with a NULL kernel this one return the TimeBase of DCE in nanoseconds.. > Q2) in case of !kernel, does "CurrentNs" return fixed value ? doesn't it mean > that the clock won't advance during simulation ? CurrentNs is called only once with NULL at the initialisation of the kernel. While writing I think it is better to pass the value of TimeBase by sim_init method.
(In reply to comment #5) > (In reply to comment #4) > > I can understand disagreement between dce and kernel clock. > > > > (In reply to comment #3) > > > static __u64 CurrentNs (struct SimKernel *kernel) > > > { > > > + if (!kernel) > > > + { > > > + return TimeBase () * 1000000000ULL; > > > + } > > > return Simulator::Now ().GetNanoSeconds (); > > > } > > > > Q1) What is the exact case of "(kernel == NULL)" ? > > I have not put any comment because it is only a temporary workaround, > because I do not want to start adding a new method in SimImported structure > in order to preserve the good working of all the available version of kernels > for DCE. > So I add a new usage the the function currentNS ie : > > we called with a NULL kernel this one return the TimeBase of DCE in > nanoseconds.. okay. > > Q2) in case of !kernel, does "CurrentNs" return fixed value ? doesn't it mean > > that the clock won't advance during simulation ? > > CurrentNs is called only once with NULL at the initialisation of the kernel. > okay. to clarify the issue, currently kernel: use CurrentNs (sim_current_ns) for jiffies, but use this for do_gettimeofday (& co) as well (which cause this problem) user: gettimeofday use a static value starting from (1262304000 == 1 Jan 2010 0:0:0), and also has Simulator::Now () to provide CurrentNs to kernel. is that correct understanding ? > While writing I think it is better to pass the value of TimeBase by sim_init > method. or TimeBase () returns 0 ?
> or TimeBase () returns 0 ? Yes it is a rapid solution ! But I am not sure the user will be happy to see date like 1 january 1970 ? I think the developer should be able to choose the scenarios departure date .