The ECN implementation model for Linux TCP in ns-2 simulator Naeem Khademi

advertisement
The ECN implementation model for Linux TCP in ns-2
simulator∗
Naeem Khademi
Networks and Distributed Systems Group
Department of Informatics, University of Oslo
Oslo, Norway
naeemk@ifi.uio.no
ABSTRACT
unsigned char cong_action_; /* Congestion Action.
Transport sender notifying transport
receiver of responses to congestion.(CWR bit
in TCP header) */
This technical report describes in details the implementation
of ECN for Linux TCP in ns-2 simulator.
/* these functions use the newer ECN names but
leaves the actual field names above to
maintain backward compat */
unsigned char& ect() { return ecn_capable_; }
/* (ECT bit in IP header) */
unsigned char& ect1() { return eem_capable_; }
/* (use ECT(1) bit in IP header instead of
ECT(0)) e.g.used for early ecn marking
(EEM) */
unsigned char& ecnecho() { return ecn_; } /* (ECN
Echo bit in TCP header) */
unsigned char& ce() { return ecn_to_echo_; } /*
(CE bit in IP header) */
unsigned char& cong_action() { return
cong_action_; } /* (CWR bit in TCP
header-old name) */
unsigned char& cwr() { return cong_action_; } /*
(CWR bit in TCP header) */
...
Keywords
TCP, ECN, Linux, ns-2;
1.
INTRODUCTION
A short story about ECN and citing relevant RFCs
2.
OPERATION OF ECN
How ECN protocol works; explain the sender-router-receiver
interaction, header flags and bits e.g. ECT(0), CE, ECE,
CWR, etc.
3.
ECN IMPLEMENTATION FOR NS-2 LINUX
TCP
Some bits, flags and functions defined in TCP header files
as well as TCP Agent class as in Listing 1 and Listing 2.
Listing 1: ECN-related variables and functions in hdr_flags
struct in common/flags.h.
struct hdr_flags {
unsigned char ecn_; /* transport receiver
notifying transport sender of ECN (ECN Echo
bit in TCP header) */
unsigned char ecn_to_echo_; /* ecn to be echoed
back in the opposite direction (CE bit in IP
header) */
unsigned char ecn_capable_; /* an ecn-capable
tranport (ECT bit in IP header) */
unsigned char eem_capable_; /* an early ecn
marking (EEM capable transport (ECT(1) bit
in IP header) */
∗PROPOSED DRAFT IN PROGRESS: Please do not redistribute!
};
Listing 2: ECN-related variables in TcpAgent class in
tcp/tcp.h.
class TcpAgent : public Agent {
...
protected:
int ecn_;
/* Explicit Congestion
Notification */
int eem_; /* Early ECN Marking */
int eem_beta; /* Early ECN Marking beta factor
*/
int cong_action_;
/* Congestion Action. True
to indicate that the sender responded to
congestion. */
int ecn_burst_; /* True when the previous ACK
packet carried ECN-Echo. */
int ecn_backoff_;
/* True when retransmit
timer should begin to be backed off. */
int ect_;
/* turn on ect bit now? */
int ect1_;
/* ect(1) bit e.g. used for early
ECN marking */
...
};
CE marking by AQM (here RED) at the router is in Listing 3
and Listing 4.
Listing 3: ECN marking indicator in queue/red.h.
next_pkts_in_flight_ = linux_.snd_cwnd; //we do
rate halving
if (linux_.icsk_ca_ops==NULL) {
slowdown(CLOSE_SSTHRESH_HALF|CLOSE_CWND_HALF);
load_to_linux();
} else {
//ok this is the linux part
linux_.snd_ssthresh =
icsk->icsk_ca_ops->ssthresh(&linux_);
linux_.snd_cwnd_cnt = 0;
linux_.bytes_acked = 0;
if (icsk->icsk_ca_ops->min_cwnd)
linux_.snd_cwnd =
icsk->icsk_ca_ops->min_cwnd(&linux_);
else
linux_.snd_cwnd = linux_.snd_ssthresh;
ncwndcuts_++;
cong_action_ = TRUE;
}
if (flag & FLAG_ECE) ++necnresponses_;
tcp_set_ca_state(TCP_CA_Recovery);
struct edp {
int setbit;
/* true to set congestion
indication bit */
...
};
class REDQueue : public Queue {
...
protected:
edp edp_;
/* early-drop params */
...
}
Listing 4: CE marking in RED queue as in queue/red.cc.
int REDQueue::drop_early(Packet* pkt) {
hdr_cmn* ch = hdr_cmn::access(pkt);
...
if (u <= edv_.v_prob) {
// DROP or MARK
edv_.count = 0;
edv_.count_bytes = 0;
hdr_flags* hf =
hdr_flags::access(pickPacketForECN(pkt));
if (edp_.setbit && hf->ect() && (!edp_.use_mark_p
|| edv_.v_prob1 < edp_.mark_p)) {
hf->ce() = 1; /* mark Congestion Experienced
bit */
/* Tell the queue monitor here - call
emark(pkt) */
return (0); // no drop
} else {
return (1); // drop
}
}
return (0); // no DROP/mark
}
TCP sender receives a packet with ECN-Echo (ECE) bit set
and sets the ECE flag. It also reacts to ECE by halving the
cwnd as shown in Listing 5.
Listing 5: Rate halving due to loss or ECE signal in
tcp/tcp-linux.cc.
void LinuxTcpAgent::recv(Packet *pkt, Handler*) {
//equivalence to tcp_ack
...
if (hdr_flags::access(pkt)->ecnecho() && ecn_ &&
(ack>1)) {
flag |= FLAG_ECE;
//ECN
}
...
}
void LinuxTcpAgent::tcp_fastretrans_alert(unsigned char
flag) {
struct inet_connection_sock *icsk = &linux_;
...
switch (linux_.icsk_ca_state) {
case TCP_CA_Recovery: break;
case TCP_CA_Loss:
//let it through
default:
//TCP_CA_Open and have loss or ECE
if (flag&(FLAG_DATA_LOST | FLAG_ECE)) {
recover_ = maxseq_;
last_cwnd_action_ = CWND_ACTION_DUPACK;
touch_cwnd();
}
}
}
Once a packet is being sent at the sender, it sets ECT(0) bitorder if ECN is turned on. If cwnd reduction (rate-halving)
has happened, it sets the CWR bit in outgoing packet’s header
in Listing 6.
Listing 6: ECT(0) and CWR marking at the TCP sender in
tcp/tcp.cc.
void TcpAgent::output(int seqno, int reason) {
...
Packet* p = allocpkt();
hdr_flags* hf = hdr_flags::access(p);
...
if (ecn_) {
hf->ect() = 1; // ECN-capable transport
}
if (cong_action_ && (!is_retransmit ||
SetCWRonRetransmit_)) {
hf->cong_action() = TRUE; /* Congestion
action. */
cong_action_ = FALSE;
}
}
4.
CONCLUSIONS
In this paper, we provided in-depth knowledge over implementation of ECN for Linux TCP in ns-2 simulator.
Download