Hi Dave
This is a response that will leverage a bit from the port stats earlier post. So there will be a bit of duplication but I want to keep it in for the sake of other forum visitors.
First let’s start with what duration_sec and duration_nsec is the time since this OpenFlow meter was created. These are not intervals but the time at what this sample was collected. This is to enable the user to eliminate the latency in the OpenFlow control channel exchange. If you query this via REST this will add even more latency.
The point in time can be calculated as follow: The total duration in nanoseconds can be computed as duration_sec*10^9+duration nsec ( Or in terms of seconds duration_sec.duration_nsec*10^-9).
As an example Assume duration_sec=9 and duration_nsec=1,000,000 then this would be
90,000,000,001,000,000 nanoseconds or 9.000,1 seconds
Note that the minimum required accuracy required by the OpenFlow spec is 1 sec.
Note the statistics is not being reset when they are queried.
Based on the data supplied and other forum questions you posted this looks like you are using Provision switches. Currently there is an issue that is being worked on since the values returned duration_sec":4294967295,"duration_nsec":4294967295 is incorrect. This will be fixed in a future version of software. Be aware that these timers can be reset to zero when the meter is being recreated for instance.
One thing to be aware of the software does poll the hardware that accelerate these flows at a certain interval so these stats sometimes take a few seconds to show up. By default on Provision this is 20 seconds you can decrease this interval but this increases the CPU utilization. Keep this in mind when tuning your sampling intervals and hardware refresh rates.
The logic below is generic for any switch that supports this.
The logic is as follows under normal circumstances
- Create a meter
- Create a flow that utilizes the meter
- Collect sample one and store the counters of interest including the duration values
- Also store the system time at which you collected this
- Sleep for the sample interval
- Collect sample two and store the counters of interest including the duration values
- Also store the system time at which you collected this
Now at this point you can subtract the sample one values from the sample two values.
You can calculate the interval over which this took place, and you can compare it to the system time interval and account for anomalies based on this for instance counters being reset or something similar, and enable you to take appropriate action.
As a workaround for the issue mentioned above while the issue mentioned for duration_sec and duration_nsec is being worked on simply base the calculation on the system time.
Sample of the exercise (I am using a switch that return duration_sec and duration_nsec correctly). I will transmit about 1000 frames of 640 bytes each that matches my flow over this interval. I used a packet generator for this.
dpid is my datapath id
tok is my x-auth-token
Start by creating a text file for the meter called meter in this case containing its json
{
"meter": {
"bands": [
{
"burst_size": 100000,
"mtype": "dscp_remark",
"prec_level": 1,
"rate": 10000
}
],
"command": "add",
"flags": [
"kbps",
"burst",
"stats"
],
"id": 1
},
"version": "1.3.0"
}
Create a text file for the metered flow called metered_flow in this case containing its json
{
"flow": {
"idle_timeout": 0,
"instructions": [
{
"apply_actions": [
{
"output": 3
}
]
},
{
"meter": 1
}
],
"match": [
{
"vlan_vid": 1
},
{
"eth_type": "ipv4"
},
{
"ipv4_src": "1.1.1.254"
},
{
"ipv4_dst": "1.1.1.1"
}
],
"priority": 30000,
"table_id": 100
}
}
Next we will create the meter and the flow
Meter:
Command
curl --header "X-Auth-Token:$tok" --header "Content-Type:application/json" --fail -ksS --request POST --url https://10.128.10.9:8443/sdn/v2.0/of/datapaths/$dpid/meters -d "@meter" | python -mjson.tool
Output
{
"meter": {
"bands": [
{
"burst_size": 100000,
"mtype": "dscp_remark",
"prec_level": 1,
"rate": 10000
}
],
"flags": [
"kbps",
"burst",
"stats"
],
"id": 1
},
"version": "1.3.0"
}
Metered flow
Command
curl --header "X-Auth-Token:$tok" --header "Content-Type:application/json" --fail -ksS --request POST --url https://10.128.10.9:8443/sdn/v2.0/of/datapaths/$dpid/flows/ -d "@metered_flow" | python -mjson.tool
Output
None
Now for the actual test
Note in this command the meter_id=1 bit matches the meter I created.
gpr@sdn1:~$ curl --header "X-Auth-Token:$tok" --header "Content-Type:application/json" --fail -ksS --request GET --url https://10.128.10.9:8443/sdn/v2.0/of/stats/meters?dpid="$dpid"\&meter_id=1 | python -mjson.tool
{
"meter_stats": [
{
"band_stats": [
{
"byte_count": 0,
"packet_count": 0
}
],
"byte_count": 0,
"duration_nsec": 542513897,
"duration_sec": 316,
"flow_count": 1,
"id": 1,
"packet_count": 0
}
],
"version": "1.3.0"
}
gpr@sdn1:~$ date +%s%N
1407519382344606359
>>>> Inject packets here, and waite long enough for the hardware to sample after injecting the packets.
gpr@sdn1:~$ curl --header "X-Auth-Token:$tok" --header "Content-Type:application/json" --fail -ksS --request GET --url https://10.128.10.9:8443/sdn/v2.0/of/stats/meters?dpid="$dpid"\&meter_id=1 | python -mjson.tool
{
"meter_stats": [
{
"band_stats": [
{
"byte_count": 0,
"packet_count": 0
}
],
"byte_count": 622000,
"duration_nsec": 959438364,
"duration_sec": 359,
"flow_count": 1,
"id": 1,
"packet_count": 1000
}
],
"version": "1.3.0"
}
gpr@sdn1:~$ date +%s%N
1407519426264780234
Sample 1
Duration1 = 316 + 542513897*10^-9 = 316.542513897 seconds Bytes1 = 0
Packet1 = 0
Systime1 = 1407519382344606359 nanoseconds = 1407519382.344606359 seconds
Duration2 = 359 + 959438364*10^-9 = 359.959438364 seconds Bytes2 = 622000
Packet2 = 1000
Systime2 = 1407519426264780234 nanoseconds = 1407519426.264780234 seconds
Duration_delta=43.416924467
Bytes_delta=622000
Packets_delta=1000
Systime_delta=43.920173875
The difference between Systime_delta and Duration_delta is not that big and I knew I used the up arrow to enter the commands so I am happy with that.
The gap is a bit large since it took me a few second to get to the traffic generator window ;).
This then gives me the following based on duration from the switch, I rounded these number.
Bytes/sec = 14326 bytes per second hiting the meter
Packets/sec = 23 packets per second hiting the meter
Off course in this case my numbers are way out since I know the switch polls these counters only once per 20 seconds. I cannot really use that to generate this measurement per second accurately in this case. My polling rate would need to be over multiple switch samples and the interval I am measuring should be a bit bigger.
I hope this helps explain this.
Kind Regards
Gerhard Roets
HP SDN Team