Commit f5985cb8 authored by Håvard Moås's avatar Håvard Moås
Browse files

Update IPFIXLIB for modification of max/min bandwidth usage data fields. Now...

Update IPFIXLIB for modification of max/min bandwidth usage data fields. Now computing both min and max over the fields 1sec, 100ms, and 10ms. havard.mork@gmail.com

git-svn-id: file:///home/svn/mapi/branches/haavardm-mapi@45 8d5bb341-7cf1-0310-8cf6-ba355fef3186
parent dca8d2e6
......@@ -385,33 +385,55 @@ static void updatePacketSizeStats(np_ctxt_t *npctxt, HashBucket *bkt, u_int len,
}
}
static u_int getDesiSecondsDistance(unsigned long long new, unsigned long long old) {
/* Returns number of milliseconds that have passed */
static u_int getMSDistance(unsigned long long new, unsigned long long old) {
unsigned long long d = new-old;
unsigned long mspassed = (float)(d / 4294967);
return mspassed/100;
return mspassed;
}
static void calculateBitrate(u_int is_min, u_int divisor, unsigned long long stamp, unsigned long long *lastupdate,
u_int32_t *rate_best, u_int32_t *averager, u_int len) {
static void calculateBitrate(u_int divisor, u_int64_t stamp, u_int64_t *lastupdate,
u_int32_t *rate_best_max, u_int32_t *rate_best_min,
u_int32_t *averager, u_int len) {
/* 'divisor' is the number of milliseconds that one slot consists of. */
/* i.e. for a total 1sec interval, there are 10x 100ms-intervals, which */
/* implies value of 100 expected */
/*
* 1sec total = 0.1sec intervals, sets mult=100/100=1, to make bytes per sec.
* .1sec total= 0.01sec intervals, sets mult=100/10=10
* Note that BITRATE_AVERAGER_SLOTS number of slots are added, so that will also
* compensate for a factor of 10.
*/
u_int i;
u_int numSlotsAdvance = getDesiSecondsDistance(stamp,*lastupdate)/divisor;
u_int numSlotsAdvance = getMSDistance(stamp,*lastupdate)/divisor;
const u_int lastslot = BITRATE_AVERAGER_SLOTS-1;
u_int32_t mult = 100/divisor;
// First: If advancing, then sum up and check for record first.
if(numSlotsAdvance > 0) {
u_int32_t sum = 0;
for(i=0; i<BITRATE_AVERAGER_SLOTS; i++) {
sum += averager[i]/divisor;
if(is_min==1 && averager[i]==MAX_UINT32) { // If any 10sec-intervals with 0, then invalid.
sum += averager[i];
// Neither min nor max will have good values at endpoints
// (actually, max will, but it is guaranteed improved later)
if(averager[i]==MAX_UINT32) {
sum = MAX_UINT32;
break;
}
}
if((is_min==1 && sum < *rate_best) || (is_min==0 && sum > *rate_best))
*rate_best = sum;
sum *= mult;
if(sum < *rate_best_min)
*rate_best_min = sum;
else if(sum!=MAX_UINT32 && sum > *rate_best_max)
*rate_best_max = sum;
*lastupdate = stamp;
}
if(numSlotsAdvance >= BITRATE_AVERAGER_SLOTS) {
// More time than in the entire averager-block has passed. Invalidate all.
memset(averager, '\0', sizeof(u_int32_t)*BITRATE_AVERAGER_SLOTS);
......@@ -420,7 +442,6 @@ static void calculateBitrate(u_int is_min, u_int divisor, unsigned long long sta
// Advance a given number of slots
memmove(averager,averager + numSlotsAdvance, sizeof(u_int32_t)*(BITRATE_AVERAGER_SLOTS-numSlotsAdvance));
memset(averager + (BITRATE_AVERAGER_SLOTS-numSlotsAdvance), '\0', numSlotsAdvance*sizeof(u_int32_t));
// averager[lastslot] = 0;
}
averager[lastslot] += len;
}
......@@ -435,24 +456,39 @@ static void updateBitrateCalculation(np_ctxt_t *npctxt, HashBucket *bkt, u_int l
// bound. As a upper bound, they are "capped" on very fast network adapters.
// (this is to avoid using 32bit data types)
if((npctxt->bitrateCalcEnabled & BITRATECALC_1SEC_MAX) != 0) {
if((npctxt->bitrateCalcEnabled & BITRATECALC_1SEC) != 0) {
if(direction==0)
calculateBitrate(0, 1, stamp, &bkt->src2dstBitrateLastUpdate1sec,&bkt->src2dstRateMax1sec,bkt->src2dstBitrateAverager1sec,len);
calculateBitrate(100, stamp, &bkt->src2dstBitrateLastUpdate1sec,
&bkt->src2dstRateMax1sec, &bkt->src2dstRateMin1sec,
bkt->src2dstBitrateAverager1sec,len);
else
calculateBitrate(0, 1, stamp, &bkt->dst2srcBitrateLastUpdate1sec,&bkt->dst2srcRateMax1sec,bkt->dst2srcBitrateAverager1sec,len);
calculateBitrate(100, stamp, &bkt->dst2srcBitrateLastUpdate1sec,
&bkt->dst2srcRateMax1sec, &bkt->dst2srcRateMin1sec,
bkt->dst2srcBitrateAverager1sec,len);
}
if((npctxt->bitrateCalcEnabled & BITRATECALC_10SEC_MIN) != 0) {
if((npctxt->bitrateCalcEnabled & BITRATECALC_100MS) != 0) {
if(direction==0)
calculateBitrate(1, 10, stamp, &bkt->src2dstBitrateLastUpdate10sec,&bkt->src2dstRateMin10sec,bkt->src2dstBitrateAverager10sec,len);
calculateBitrate(10, stamp, &bkt->src2dstBitrateLastUpdate100ms,
&bkt->src2dstRateMax100ms, &bkt->src2dstRateMin100ms,
bkt->src2dstBitrateAverager100ms,len);
else
calculateBitrate(1, 10, stamp, &bkt->dst2srcBitrateLastUpdate10sec,&bkt->dst2srcRateMin10sec,bkt->dst2srcBitrateAverager10sec,len);
calculateBitrate(10, stamp, &bkt->dst2srcBitrateLastUpdate100ms,
&bkt->dst2srcRateMax100ms, &bkt->dst2srcRateMin100ms,
bkt->dst2srcBitrateAverager100ms,len);
}
if((npctxt->bitrateCalcEnabled & BITRATECALC_100SEC_MIN) != 0) {
if((npctxt->bitrateCalcEnabled & BITRATECALC_10MS) != 0) {
if(direction==0)
calculateBitrate(1, 100, stamp, &bkt->src2dstBitrateLastUpdate100sec,&bkt->src2dstRateMin100sec,bkt->src2dstBitrateAverager100sec,len);
calculateBitrate(1, stamp, &bkt->src2dstBitrateLastUpdate10ms,
&bkt->src2dstRateMax10ms,&bkt->src2dstRateMin10ms,
bkt->src2dstBitrateAverager10ms,len);
else
calculateBitrate(1, 100, stamp, &bkt->dst2srcBitrateLastUpdate100sec,&bkt->dst2srcRateMin100sec,bkt->dst2srcBitrateAverager100sec,len);
calculateBitrate(1, stamp, &bkt->dst2srcBitrateLastUpdate10ms,
&bkt->dst2srcRateMax10ms, &bkt->dst2srcRateMin10ms,
bkt->dst2srcBitrateAverager10ms,len);
}
}
......@@ -703,26 +739,33 @@ void addPktToHash(np_ctxt_t *npctxt,
// Clear the "time slot" buffers that is used to efficiently find highest/lowest
// average xfer amount for a period of time.
// Clear all, also if only one will be used.
memset(bkt->src2dstBitrateAverager1sec, '\0', sizeof(u_int32_t)*BITRATE_AVERAGER_SLOTS);
memset(bkt->src2dstBitrateAverager10sec, 0xFF, sizeof(u_int32_t)*BITRATE_AVERAGER_SLOTS);
memset(bkt->src2dstBitrateAverager100sec, 0xFF, sizeof(u_int32_t)*BITRATE_AVERAGER_SLOTS);
memset(bkt->dst2srcBitrateAverager1sec, '\0', sizeof(u_int32_t)*BITRATE_AVERAGER_SLOTS);
memset(bkt->dst2srcBitrateAverager10sec, 0xFF, sizeof(u_int32_t)*BITRATE_AVERAGER_SLOTS);
memset(bkt->dst2srcBitrateAverager100sec, 0xFF, sizeof(u_int32_t)*BITRATE_AVERAGER_SLOTS);
memset(bkt->src2dstBitrateAverager1sec, '\0', sizeof(u_int32_t)*BITRATE_AVERAGER_SLOTS);
memset(bkt->src2dstBitrateAverager100ms, 0xFF, sizeof(u_int32_t)*BITRATE_AVERAGER_SLOTS);
memset(bkt->src2dstBitrateAverager10ms, 0xFF, sizeof(u_int32_t)*BITRATE_AVERAGER_SLOTS);
memset(bkt->dst2srcBitrateAverager1sec, '\0', sizeof(u_int32_t)*BITRATE_AVERAGER_SLOTS);
memset(bkt->dst2srcBitrateAverager100ms, 0xFF, sizeof(u_int32_t)*BITRATE_AVERAGER_SLOTS);
memset(bkt->dst2srcBitrateAverager10ms, 0xFF, sizeof(u_int32_t)*BITRATE_AVERAGER_SLOTS);
bkt->src2dstBitrateLastUpdate1sec = stamp;
bkt->src2dstBitrateLastUpdate10sec = stamp;
bkt->src2dstBitrateLastUpdate100sec = stamp;
bkt->src2dstBitrateLastUpdate100ms = stamp;
bkt->src2dstBitrateLastUpdate10ms = stamp;
bkt->dst2srcBitrateLastUpdate1sec = stamp;
bkt->dst2srcBitrateLastUpdate10sec = stamp;
bkt->dst2srcBitrateLastUpdate100sec = stamp;
bkt->dst2srcBitrateLastUpdate100ms = stamp;
bkt->dst2srcBitrateLastUpdate10ms = stamp;
}
bkt->src2dstRateMax1sec = 0x00000000;
bkt->src2dstRateMin10sec = MAX_UINT32;
bkt->src2dstRateMin100sec= MAX_UINT32;
bkt->dst2srcRateMax1sec = 0x00000000;
bkt->dst2srcRateMin10sec = MAX_UINT32;
bkt->dst2srcRateMin100sec= MAX_UINT32;
bkt->src2dstRateMax1sec = 0;
bkt->src2dstRateMin1sec = MAX_UINT32;
bkt->src2dstRateMax100ms = 0;
bkt->src2dstRateMin100ms = MAX_UINT32;
bkt->src2dstRateMax10ms = 0;
bkt->src2dstRateMin10ms = MAX_UINT32;
bkt->dst2srcRateMax1sec = 0;
bkt->dst2srcRateMin1sec = MAX_UINT32;
bkt->dst2srcRateMax100ms = 0;
bkt->dst2srcRateMin100ms = MAX_UINT32;
bkt->dst2srcRateMax10ms = 0;
bkt->dst2srcRateMin10ms = MAX_UINT32;
bkt->src2dstMinPktSize = bkt->dst2srcMinPktSize = 0xFFFF;
bkt->src2dstMaxPktSize = bkt->dst2srcMaxPktSize = 0x0000;
......
......@@ -197,9 +197,9 @@ typedef struct ipV4Fragment {
// Bitset for bitrateCalcEnabled (in struct np_ctxt_t)
#define BITRATECALC_NONE 0
#define BITRATECALC_1SEC_MAX 1
#define BITRATECALC_10SEC_MIN 2
#define BITRATECALC_100SEC_MIN 4
#define BITRATECALC_1SEC 1
#define BITRATECALC_100MS 2
#define BITRATECALC_10MS 4
typedef struct {
void *mapi_ctxt; /* MAPI shared memory context */
......
......@@ -1054,7 +1054,7 @@ npInitContext(void)
npctxt->traceMode = 0;
npctxt->flowExportDelay = 100;
npctxt->idleTimeout = DUMP_TIMEOUT;
npctxt->lifetimeTimeout = 4*DUMP_TIMEOUT;
npctxt->lifetimeTimeout = 8*DUMP_TIMEOUT;
npctxt->sendTimeout = 5;
npctxt->tmpltTimeout = 2*DUMP_TIMEOUT;
npctxt->useNetFlow = 0xFF;
......
......@@ -118,25 +118,28 @@ typedef struct hashBucket {
u_int16_t src2dstMinPktSize, dst2srcMinPktSize;
u_int16_t src2dstMaxPktSize, dst2srcMaxPktSize;
u_int32_t src2dstBitrateAverager1sec[BITRATE_AVERAGER_SLOTS]; // xfer last 1sec in .1sec slots
u_int32_t src2dstBitrateAverager10sec[BITRATE_AVERAGER_SLOTS]; // xfer last 10sec in 1sec slots
u_int32_t src2dstBitrateAverager100sec[BITRATE_AVERAGER_SLOTS]; // xfer last 100sec in 10sec slots
u_int32_t src2dstBitrateAverager1sec[BITRATE_AVERAGER_SLOTS]; // xfer last 1sec
u_int32_t src2dstBitrateAverager100ms[BITRATE_AVERAGER_SLOTS];// xfer last 100ms
u_int32_t src2dstBitrateAverager10ms[BITRATE_AVERAGER_SLOTS]; // xfer last 10ms
unsigned long long src2dstBitrateLastUpdate1sec;
unsigned long long src2dstBitrateLastUpdate10sec;
unsigned long long src2dstBitrateLastUpdate100sec;
u_int32_t src2dstRateMax1sec; // Avg rate within 1sec, max reading
u_int32_t src2dstRateMin10sec; // Avg rate within 10sec, min reading
u_int32_t src2dstRateMin100sec; // Avg rate within 100sec, min reading
u_int32_t dst2srcBitrateAverager1sec[BITRATE_AVERAGER_SLOTS]; // xfer last 1sec in .1sec slots
u_int32_t dst2srcBitrateAverager10sec[BITRATE_AVERAGER_SLOTS]; // xfer last 10sec in 1sec slots
u_int32_t dst2srcBitrateAverager100sec[BITRATE_AVERAGER_SLOTS]; // xfer last 100sec in 10sec slots
unsigned long long src2dstBitrateLastUpdate100ms;
unsigned long long src2dstBitrateLastUpdate10ms;
u_int32_t dst2srcBitrateAverager1sec[BITRATE_AVERAGER_SLOTS]; // xfer last 1sec
u_int32_t dst2srcBitrateAverager100ms[BITRATE_AVERAGER_SLOTS]; // xfer last 100ms
u_int32_t dst2srcBitrateAverager10ms[BITRATE_AVERAGER_SLOTS]; // xfer last 10ms
unsigned long long dst2srcBitrateLastUpdate1sec;
unsigned long long dst2srcBitrateLastUpdate10sec;
unsigned long long dst2srcBitrateLastUpdate100sec;
u_int32_t dst2srcRateMax1sec; // Avg rate within 1sec, max reading
u_int32_t dst2srcRateMin10sec; // Avg rate within 10sec, min reading
u_int32_t dst2srcRateMin100sec; // Avg rate within 100sec, min reading
unsigned long long dst2srcBitrateLastUpdate100ms;
unsigned long long dst2srcBitrateLastUpdate10ms;
u_int32_t src2dstRateMax1sec, dst2srcRateMax1sec;
u_int32_t src2dstRateMax100ms, dst2srcRateMax100ms;
u_int32_t src2dstRateMax10ms, dst2srcRateMax10ms;
u_int32_t src2dstRateMin1sec, dst2srcRateMin1sec;
u_int32_t src2dstRateMin100ms, dst2srcRateMin100ms;
u_int32_t src2dstRateMin10ms, dst2srcRateMin10ms;
u_int16_t src2dstPktlenIpv4;
u_int16_t dst2srcPktlenIpv4;
......
......@@ -39,9 +39,12 @@
#define FID_HISTOGRAM_PKT_LNGTH 32769
#define FID_HISTOGRAM_PKT_DIST 32770
#define FID_RATE_1SEC_MAX 32771
#define FID_RATE_10SEC_MIN 32772
#define FID_RATE_100SEC_MIN 32773
#define FID_RATE_1SEC_MAX 32780
#define FID_RATE_1SEC_MIN 32781
#define FID_RATE_100MS_MAX 32782
#define FID_RATE_100MS_MIN 32783
#define FID_RATE_10MS_MAX 32784
#define FID_RATE_10MS_MIN 32785
#define FID_PAYLOAD 32776
#ifndef __KERNEL__
......@@ -708,7 +711,7 @@ static V9TemplateId ver9_templates[] = {
{ 42, 4, "TOTAL_FLOWS_EXP" },
// NOT 43-59
{ 60, 1, "IP_PROTOCOL_VERSION" },
{ 61, 1, "DIRECTION" },
//{ 61, 1, "DIRECTION" },
//{ 62, 16, "IPV6_NEXT_HOP" },
//{ 63, 16, "BPG_IPV6_NEXT_HOP" },
{ 64, 4, "IPV6_OPTION_HEADERS" },
......@@ -771,9 +774,12 @@ static V9TemplateId ver9_templates[] = {
// Note that 32768 is reserved (ent.mark = 1, ent.id = 0)
{ FID_HISTOGRAM_PKT_LNGTH, PKTSZ_HISTOGRAM_SLOTS*sizeof(u_int8_t), "HISTOGRAM_PKT_LNGTH" },
{ FID_HISTOGRAM_PKT_DIST, PKTDIST_HISTOGRAM_SLOTS*sizeof(u_int8_t), "HISTOGRAM_PKT_DIST" },
{ FID_RATE_1SEC_MAX, 4, "RATE_1SEC_MAX_TRANSFER" },
{ FID_RATE_10SEC_MIN, 4, "RATE_10SEC_MIN_TRANSFER" },
{ FID_RATE_100SEC_MIN, 4, "RATE_100SEC_MIN_TRANSFER" },
{ FID_RATE_1SEC_MAX, 4, "MAXRATE_1SEC" },
{ FID_RATE_1SEC_MIN, 4, "MINRATE_1SEC" },
{ FID_RATE_100MS_MAX, 4, "MAXRATE_100MS" },
{ FID_RATE_100MS_MIN, 4, "MINRATE_100MS" },
{ FID_RATE_10MS_MAX, 4, "MAXRATE_10MS" },
{ FID_RATE_10MS_MIN, 4, "MINRATE_10MS" },
{ FID_PAYLOAD, PAYLOAD_EXCERPT_MAX, "PAYLOAD" },
{ 0, 0, NULL }
......@@ -1146,9 +1152,9 @@ static void handleTemplate(np_ctxt_t *npctxt, V9TemplateId *theTemplate,
case 60: /* IP_PROTOCOL_VERSION */
copyInt8(4, outBuffer, outBufferBegin, outBufferMax); /* FIX */
break;
case 61:
copyInt8(direction, outBuffer, outBufferBegin, outBufferMax); /* FIX */
break;
//case 61:
// copyInt8(direction, outBuffer, outBufferBegin, outBufferMax); /* FIX */
// break;
case 64:
copyInt32(direction==0?theFlow->optionsIPV6src2dst:theFlow->optionsIPV6dst2src,
outBuffer, outBufferBegin, outBufferMax);
......@@ -1350,14 +1356,23 @@ static void handleTemplate(np_ctxt_t *npctxt, V9TemplateId *theTemplate,
case FID_HISTOGRAM_PKT_DIST: // HISTOGRAM_PKT_DIST
copyInt32ArrayToRelativeInt8(direction==0?theFlow->src2dstPktDistHistogram:theFlow->dst2srcPktDistHistogram,outBuffer,outBufferBegin,outBufferMax,PKTDIST_HISTOGRAM_SLOTS);
break;
case FID_RATE_1SEC_MAX: // RATE_1SEC_MAX_TRANSFER
case FID_RATE_1SEC_MAX:
copyInt32(direction==0?theFlow->src2dstRateMax1sec:theFlow->dst2srcRateMax1sec, outBuffer,outBufferBegin,outBufferMax);
break;
case FID_RATE_10SEC_MIN: // RATE_10SEC_MIN_TRANSFER
copyInt32(direction==0?theFlow->src2dstRateMin10sec:theFlow->dst2srcRateMin10sec, outBuffer, outBufferBegin,outBufferMax);
case FID_RATE_1SEC_MIN:
copyInt32(direction==0?theFlow->src2dstRateMin1sec:theFlow->dst2srcRateMin1sec, outBuffer,outBufferBegin,outBufferMax);
break;
case FID_RATE_100MS_MAX:
copyInt32(direction==0?theFlow->src2dstRateMax100ms:theFlow->dst2srcRateMax100ms, outBuffer, outBufferBegin,outBufferMax);
break;
case FID_RATE_100MS_MIN:
copyInt32(direction==0?theFlow->src2dstRateMin100ms:theFlow->dst2srcRateMin100ms, outBuffer, outBufferBegin,outBufferMax);
break;
case FID_RATE_100SEC_MIN: // RATE_100SEC_MIN_TRANSFER
copyInt32(direction==0?theFlow->src2dstRateMin100sec:theFlow->dst2srcRateMin100sec, outBuffer, outBufferBegin,outBufferMax);
case FID_RATE_10MS_MAX:
copyInt32(direction==0?theFlow->src2dstRateMax10ms:theFlow->dst2srcRateMax10ms, outBuffer, outBufferBegin,outBufferMax);
break;
case FID_RATE_10MS_MIN:
copyInt32(direction==0?theFlow->src2dstRateMin10ms:theFlow->dst2srcRateMin10ms, outBuffer, outBufferBegin,outBufferMax);
break;
case FID_PAYLOAD:
exportPayload(npctxt, theFlow, direction, theTemplate,
......@@ -1405,14 +1420,18 @@ turnOnSpecialProcessing(np_ctxt_t *npctxt, u_int element) {
break;
case FID_HISTOGRAM_PKT_DIST:
npctxt->histPktDistEnabled = 1;
case FID_RATE_1SEC_MAX:
npctxt->bitrateCalcEnabled |= BITRATECALC_1SEC_MAX;
case FID_RATE_1SEC_MAX:
case FID_RATE_1SEC_MIN:
npctxt->bitrateCalcEnabled |= BITRATECALC_1SEC;
break;
case FID_RATE_10SEC_MIN:
npctxt->bitrateCalcEnabled |= BITRATECALC_10SEC_MIN;
case FID_RATE_100MS_MAX:
case FID_RATE_100MS_MIN:
npctxt->bitrateCalcEnabled |= BITRATECALC_100MS;
break;
case FID_RATE_100SEC_MIN:
npctxt->bitrateCalcEnabled |= BITRATECALC_100SEC_MIN;
case FID_RATE_10MS_MAX:
case FID_RATE_10MS_MIN:
npctxt->bitrateCalcEnabled |= BITRATECALC_10MS;
break;
}
return;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment