Commit 649ec1ea authored by Nigel Kukard's avatar Nigel Kukard
Browse files

* Added ECN support

parent 24f43d81
......@@ -161,11 +161,13 @@ static unsigned char autoClassify_tos(struct ip_packet_t *ip_packet, unsigned ch
{
unsigned char prio = 0;
// Get type of service
unsigned char tos = IPTOS_TOS(ip_packet->tos);
// unsigned char ecn = AUTOCLASS_TOS_ECN_MASK(ip_packet->tos);
unsigned char tos = AUTOCLASS_TOS_MASK(ip_packet->tos);
// unsigned char prec = AUTOCLASS_TOS_PREC_MASK(ip_packet->tos);
// Decide what we doing...
if (tos == IPTOS_LOWDELAY)
if (tos == AUTOCLASS_TOS_LOWDELAY)
{
/*
* 1. LOW DELAY
......@@ -174,7 +176,7 @@ static unsigned char autoClassify_tos(struct ip_packet_t *ip_packet, unsigned ch
*/
prio = 10;
}
else if (tos == IPTOS_THROUGHPUT)
else if (tos == AUTOCLASS_TOS_THROUGHPUT)
{
/*
* 2. THROUGHPUT
......@@ -182,22 +184,13 @@ static unsigned char autoClassify_tos(struct ip_packet_t *ip_packet, unsigned ch
* - low drop probability
*/
}
else if (tos == IPTOS_RELIABILITY)
else if (tos == AUTOCLASS_TOS_RELIABILITY)
{
/*
* 3. RELIABILITY
* - low drop probability
*/
}
else if (tos == IPTOS_MINCOST)
{
/*
* 4. MIN COST
* - PRIO 90
* - high drop probability
*/
prio = 90;
}
return prio;
}
......
......@@ -365,7 +365,18 @@ static unsigned int processPktQueue(struct runnerData_t *runnerData, struct pktQ
{
// Re-inject packet for processing, check if it was ok...
g_mutex_lock(runnerData->IPQLock);
status = ipq_set_verdict(runnerData->IPQHandle, PKT_ID(packet), NF_ACCEPT, 0, NULL);
// Check if our packet was changed
if (packet->changed)
{
struct ip_packet_t *ip_packet = (struct ip_packet_t *) packet->payload->payload;
// Send packet back modified
status = ipq_set_verdict(runnerData->IPQHandle, PKT_ID(packet), NF_ACCEPT, ip_packet->tot_len, (unsigned char *) ip_packet);
}
else
status = ipq_set_verdict(runnerData->IPQHandle, PKT_ID(packet), NF_ACCEPT, 0, NULL);
g_mutex_unlock(runnerData->IPQLock);
if (status < 0)
{
......
......@@ -92,6 +92,7 @@ static int queuePacket(struct runnerData_t *runnerData, unsigned long int nfmark
int status;
int result;
int drop = 0;
struct ip_packet_t *ip_packet = (struct ip_packet_t *) packet->payload->payload;
// Our find functions
......@@ -138,15 +139,8 @@ static int queuePacket(struct runnerData_t *runnerData, unsigned long int nfmark
// Now lets see if we don't have a queue... this means AUTO!
if (!foundQueue)
{
struct ip_packet_t *ip_packet = (struct ip_packet_t *) packet->payload->payload;
unsigned char prio = 0;
/*
fprintf(stderr,"auto packet queue -> protocol = %i, src = %i.%i.%i.%i, dest = %i.%i.%i.%i, tos = 0x%x\n", ip_packet->protocol,
ip_packet->u_saddr.addr.a, ip_packet->u_saddr.addr.b, ip_packet->u_saddr.addr.c, ip_packet->u_saddr.addr.d,
ip_packet->u_daddr.addr.a, ip_packet->u_daddr.addr.b, ip_packet->u_daddr.addr.c, ip_packet->u_daddr.addr.d,
IPTOS_PREC(ip_packet->tos));
*/
prio = autoClassify(ip_packet,foundFlow->prioClassifier);
......@@ -191,8 +185,24 @@ static int queuePacket(struct runnerData_t *runnerData, unsigned long int nfmark
prob = avgProb + curProb;
// Check if we should drop packet
drop = drand < prob;
}
// If queue is 10% full, set CE bit if we ECN capable
if (!drop && (avgQueueSize / curQueueSize) > 0.10)
{
unsigned char ecn = AUTOCLASS_TOS_ECN_MASK(ip_packet->tos);
// We are ECN capable
if (ecn < 3)
{
// Set CE codepoint to communicate congestion
ip_packet->tos |= AUTOCLASS_TOS_ECN_CE;
// Tell flowRunner we modified the packet
packet->changed = 1;
}
}
}
}
// Check if we must pass the packet
......@@ -327,6 +337,9 @@ void *IPQRunner(void *data)
// Copy packet
memcpy(packet->payload,m,pkt_len);
// Set packet as not changed
packet->changed = 0;
// Queue the packet...
status = queuePacket(runnerData,packet->payload->mark,packet);
if (status < 0)
......
......@@ -35,6 +35,28 @@
#define AUTOCLASS_TOS 2
// Type of Service / DSCP / ECN ... etc
#define AUTOCLASS_TOS_ECN_MASK(tos) ((tos) & 0x03) // Mask of all ECN bits
#define AUTOCLASS_TOS_ECN_ECT0 0x01
#define AUTOCLASS_TOS_ECN_ECT1 0x02
#define AUTOCLASS_TOS_ECN_CE 0x03
#define AUTOCLASS_TOS_MASK(tos) ((tos) & 0x1c) // Mask of all TOS bits
#define AUTOCLASS_TOS_RELIABILITY 0x04 // High Reliability
#define AUTOCLASS_TOS_THROUGHPUT 0x08 // High Throughput
#define AUTOCLASS_TOS_LOWDELAY 0x10 // Low Delay
#define AUTOCLASS_TOS_PREC_MASK(tos) ((tos) & 0xe0) // Mask of all PREC bits
#define AUTOCLASS_TOS_PREC_ROUTINE 0x00 // Routine
#define AUTOCLASS_TOS_PREC_PRIORITY 0x20 // Priority
#define AUTOCLASS_TOS_PREC_IMMEDIATE 0x40 // Immediate
#define AUTOCLASS_TOS_PREC_FLASH 0x60 // Flash
#define AUTOCLASS_TOS_PREC_FLASH_OVERRIDE 0x80 // Flash Override
#define AUTOCLASS_TOS_PREC_CRITIC_ECP 0xa0 // Critic/ECP
#define AUTOCLASS_TOS_PREC_INTERNETWORK_CONTROL 0xc0 // Internetwork control
#define AUTOCLASS_TOS_PREC_NETWORK_CONTROL 0xe0 // Network control
// Auto classify packet and return priority (1 - best, 100 - worst)
unsigned char autoClassify(struct ip_packet_t *ip_packet, unsigned char prioClassifier);
......
......@@ -81,9 +81,11 @@ struct flowData_t
};
// This is used in the queueing and is the item used in the queue
struct packet_t
{
ipq_packet_msg_t *payload;
unsigned char changed;
};
......
......@@ -176,10 +176,12 @@ void updateGroups(
int pktBursted);
// Flow runner thread
void *flowRunner(void *data);
// Message log facility
void logMessage(int priority, const char *fmt, ...);
// Flow runner thread
void *flowRunner(void *data);
// Check if we will exceed flow queuing limits
......@@ -189,7 +191,5 @@ static inline int will_exceed_flow_queue(struct flow_t *flow, unsigned int pktSi
(flow->curQueueSize + pktSize >= flow->maxQueueSize && flow->maxQueueSize != 0));
}
extern void logMessage(int priority, const char *fmt, ...);
#endif
Supports Markdown
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