Mininet + NS3 for SDN and WIFI simulations
QoS Example:
h1(192.168.0.1)--wireless
link (802.11e EDCF supported)--s0 ( AP + open vswitch)--wired
link--h3(192.168.0.3)
h2
(192.168.0.2)--wireless link(802.11e EDCF supported)--
Prerequistes
1. virtual machine: download (This
work is based on https://github.com/mininet/mininet/wiki/Link-modeling-using-ns-3 .
I have added the lxde for graphical mode operation. I also
added some examples under /home/mininet/examples/ns3 for SDN and WIFI simulations. Please
download the ova file. You can useVirtualBox: Import Appliance or Vmware to
use this vm. Note: when you have downloaded the
mininet-ns3.ova.rar, please directly change the file name to mininet-ns3.ova.)
2. Change the wifi
source codes in ns-allinone-3.17 to support the mapping of ToS field in the IP
header to the IEEE 802.11 qos tag in the MAC header.
ToS |
Access Category |
0 |
AC_BE |
1 |
AC_BK |
2 |
AC_BK |
3 |
AC_BE |
4 |
AC_VI |
5 |
AC_VI |
6 |
AC_VO |
7 |
AC_VO |
2.1 go to
~/ns-allinone-3.17/ns-3.17/src/wifi/model directory and open sta-wifi-mac.cc.
(add the red lines in the corresponding places.)
void StaWifiMac::Enqueue
(Ptr<const Packet> packet, Mac48Address to) { NS_LOG_FUNCTION (this << packet
<< to); if (!IsAssociated ()) { NotifyTxDrop
(packet);
TryToEnsureAssociated (); return; } WifiMacHeader hdr; Ptr<Packet> q
= packet->Copy(); uint8_t const
*mydata=q->PeekData(); uint8_t tos = 0; if(mydata[8]==69) tos = mydata[9]; // If we are not a QoS AP then we
definitely want to use AC_BE to // transmit the packet. A TID of zero
will map to AC_BE (through \c // QosUtilsMapTidToAc()), so we use
that as our default here. uint8_t tid = 0; // For now, an AP that supports QoS
does not support non-QoS // associations, and vice versa. In
future the AP model should // support simultaneously associated
QoS and non-QoS STAs, at which // point there will need to be
per-association QoS state maintained // by the association state machine,
and consulted here. if (m_qosSupported) { hdr.SetType
(WIFI_MAC_QOSDATA);
hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
hdr.SetQosNoEosp ();
hdr.SetQosNoAmsdu (); //
Transmission of multiple frames in the same TXOP is not // supported
for now
hdr.SetQosTxopLimit (0); // Fill in the
QoS control field in the MAC header tid = QosUtilsGetTidForPacket (packet); // Any value
greater than 7 is invalid and likely indicates that // the packet
had no QoS tag, so we revert to zero, which'll // mean that
AC_BE is used. if (tid >=
7) {
tid = 0; } //added by
smallko if (tos
> 7 || tos <=0)
tid = 0; else
tid = tos;
//printf("StaWifiMac::Enqueue, tid=%d\n", tid); hdr.SetQosTid
(tid); } else {
hdr.SetTypeData (); } hdr.SetAddr1 (GetBssid ()); hdr.SetAddr2 (m_low->GetAddress
()); hdr.SetAddr3 (to); hdr.SetDsNotFrom (); hdr.SetDsTo (); if (m_qosSupported) { // Sanity
check that the TID is valid NS_ASSERT (tid
< 8);
m_edca[QosUtilsMapTidToAc (tid)]->Queue (packet, hdr); } else {
m_dca->Queue (packet, hdr); } } |
2.2 go to
~/ns-allinone-3.17/ns-3.17/src/wifi/model directory and open ap-wifi-mac.cc.
(add the red lines in the corresponding places.)
void ApWifiMac::ForwardDown
(Ptr<const Packet> packet, Mac48Address from,
Mac48Address to, uint8_t tid) { NS_LOG_FUNCTION (this << packet
<< from << to << static_cast<uint32_t> (tid)); WifiMacHeader hdr; // For now, an AP that supports QoS does
not support non-QoS // associations, and vice versa. In
future the AP model should // support simultaneously associated
QoS and non-QoS STAs, at which // point there will need to be
per-association QoS state maintained // by the association state machine,
and consulted here. Ptr<Packet> q =
packet->Copy(); uint8_t const
*mydata=q->PeekData(); uint8_t tos = 0; if(mydata[8]==69) tos = mydata[9]; if (tos > 7 || tos <=0) tid = 0; else tid = tos; if (m_qosSupported) { hdr.SetType
(WIFI_MAC_QOSDATA);
hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
hdr.SetQosNoEosp ();
hdr.SetQosNoAmsdu (); //
Transmission of multiple frames in the same TXOP is not // supported
for now hdr.SetQosTxopLimit
(0); // Fill in the
QoS control field in the MAC header
//printf("ApWifiMac::ForwardDown, tid=%d\n", tid); hdr.SetQosTid
(tid); } else {
hdr.SetTypeData (); } hdr.SetAddr1 (to); hdr.SetAddr2 (GetAddress ()); hdr.SetAddr3 (from); hdr.SetDsFrom (); hdr.SetDsNotTo (); if (m_qosSupported) { // Sanity
check that the TID is valid NS_ASSERT (tid
< 8);
m_edca[QosUtilsMapTidToAc (tid)]->Queue (packet, hdr); } else { m_dca->Queue (packet,
hdr); } } |
2.3 recompile ns3. go
to ns-allinone-3.17/ns-3.17 and type "./waf" to recompile.
3. Change the ns3.py
setting.
3.1 go to
~/mininet/mininet and open ns3.py
class
WIFISegment( object ):
"""Equivalent of radio WiFi channel. Only Ap
and WDS devices support SendFrom().""" def __init__( self ): #
Helpers instantiation.
self.channelhelper = ns.wifi.YansWifiChannelHelper.Default()
self.phyhelper = ns.wifi.YansWifiPhyHelper.Default() self.wifihelper =
ns.wifi.WifiHelper.Default() #self.machelper
= ns.wifi.NqosWifiMacHelper.Default()
self.machelper = ns.wifi.QosWifiMacHelper.Default() ........................................................................................................ |
3.2 recompile mininet
go to ~/mininet and
type "sudo make install" to recompile mininet
Usage:
1. Put the following
file (test-wifi5.py) under ~/mininet/example/ns3
import
rlcompleter import readline import time from mininet.net import
Mininet from mininet.node
import Node, Switch from mininet.link
import Link, Intf from mininet.log
import setLogLevel, info from mininet.cli
import CLI import
mininet.ns3 from mininet.ns3
import WIFISegment from mininet.node
import OVSController from mininet.link
import TCLink import ns.wifi readline.parse_and_bind("tab:
complete") if __name__ ==
'__main__': setLogLevel( 'info' ) net = Mininet(
controller=OVSController ) c0 = net.addController(
'c0' ) info( '*** Adding hosts\n'
) h1 = net.addHost( 'h1',
ip='192.168.0.1' ) h2 = net.addHost( 'h2',
ip='192.168.0.2' ) h3 = net.addHost( 'h3',
ip='192.168.0.3' ) info( '*** Adding
switch\n' ) s0 = net.addSwitch( 's0' ) s0.listenPort = 6634 c0.start() s0.start( [c0] ) linkopts=dict( bw=100,
delay='1ms', loss=0 ) TCLink( s0, h3, **linkopts
) #net.hosts.append( s0 ) net.hosts.append( h1 ) net.hosts.append( h2 ) wifi = WIFISegment() wifi.addAp( s0 ) wifi.addSta( h1 ) wifi.addSta( h2 ) wifi.phyhelper.EnablePcap(
"s0-trace.pcap", s0.nsNode.GetDevice( 0 ), True, True ); net.start() mininet.ns3.start() CLI(net) |
2. Run the script.
(The h1 will first send out one ping with ToS (0x6) which is corresponding to
VOICE service to h3. Then one ping with ToS (0x1) which is corresponding to
Background service is sent to h3. Followed by one ping with ToS (0x4) and one
ping with ToS (0x0).
After running the
script, open the captured file with wireshark.
Dr. Chih-Heng Ke
Department of Computer Science and
Information Engineering, National Quemoy University, Kinmen, Taiwan
Email: smallko@gmail.com