PointToPointNetDevice doesn't support TapBridgeHelper
I have created two containers one left and one right. I had a code given to me and was asked to attached left to one of csma nodes and right to one of the server nodes. So below I attached the left tap to one of the csma nodes.
NetDeviceContainer csmaDevices;
csmaDevices = csma.Install (csmaNodes);
// Use the TapBridgeHelper to connect to the pre-configured tap devices for
// the left side. We go with "UseBridge" mode since the CSMA devices support
// promiscuous mode and can therefore make it appear that the bridge is
// extended into ns-3. The install method essentially bridges the specified
// tap to the specified CSMA device.
TapBridgeHelper tapBridge;
tapBridge.SetAttribute ("Mode", StringValue ("UseBridge"));
tapBridge.SetAttribute ("DeviceName", StringValue ("tap-left"));
tapBridge.Install (csmaNodes.Get (0), csmaDevices.Get (0));
I had no issue attaching left to one of the csmaNodes(Client).
My issue is on the server side.
// set remote Servers
TimeValue val (Time("0ms"));
std::vector<
for(uint32_t i=0; i<derDeviceAdjacencyList.size (); ++i)
{
std::ostringstream delaySt;
delaySt << 15 + (i) * 35 << "ms";
std::ostringstream dataRate;
dataRate << 15 - (i) * 3 << "Mbps";
val.Set(Time(delaySt.str())); // required for delays
p2p.SetDeviceAttribute ("DataRate", StringValue (dataRate.str()));
p2p.SetDeviceAttribute ("Mtu", UintegerValue (1500));
p2p.SetChannelAttribute ("Delay", val);
derDeviceAdjacencyList[i] = p2p.Install (derAdjacencyList[i]);
//csmaDevices = csma.Install (csmaNodes);
}
TapBridgeHelper tapBridge;
tapBridge.SetAttribute ("DeviceName", StringValue ("tap-right"));
tapBridge.Install (derNodes.Get (1), derDeviceAdjacencyList[1].Get(1));
This is the output I get from the terminal :
Waf: Entering directory `/home/dt0803/repos/ns-3-allinone/ns-3-dev/build'
[ 885/2299] cxx: scratch/Topology.cc -> build/scratch/Topology.cc.4.o
[2272/2299] cxxprogram: build/scratch/Topology.cc.4.o -> build/scratch/Topology
Waf: Leaving directory `/home/dt0803/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (5.413s)
Create nodes.
Create channels.
MTU P2P 1500
msg="TapBridge::SetBridgedDevice: Device does not support SendFrom: cannot be added to bridge.", file=../src/tap-bridge/model/tap-bridge.cc, line=901
terminate called without an active exception
Command ['/home/dt0803/repos/ns-3-allinone/ns-3-dev/build/scratch/Topology'] terminated with signal SIGIOT. Run it under a debugger to get more information (./waf --run <program> --command-template="gdb --args %s <args>").
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
// v3: learner contacts multiple DERs sending messages of different size....
// Default Network topology, 9 nodes in a star
/*
n2 n3 n4
\ | /
\|/
n1---n0---n5
/| \
/ | \
n8 n7 n6
*/
// Default Network Topology
// n6 n7 n8
// \ | /
// \|/
// 10.1.150.0
// n5--- n0 -------------- n1 n2 n3 n4
// point-to-point | | | |
// ================
// LAN 10.1.200.0
// - CBR Traffic goes from the star "arms" to the "hub"
// - Tracing of queues and packet receptions to file
// "tcp-star-server.tr"
// - pcap traces also generated in the following files
// "tcp-star-server-$n-$i.pcap" where n and i represent node and interface
// numbers respectively
// Usage examples for things you might want to tweak:
// ./waf --run="tcp-star-server"
// ./waf --run="tcp-star-server --nNodes=25"
// ./waf --run="tcp-star-server --nNodes=25 --mNodes=12"
// ./waf --run="tcp-star-server --ns3::LRApplication::DataRate=10000"
//
// See the ns-3 tutorial for more info on the command line:
// http://www.nsnam.org/tutorials.html
#include <fstream>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <cassert>
#include <vector>
#include <ns3/gnuplot.h>
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/csma-module.h"
#include "ns3/flow-monitor-helper.h"
#include "ns3/flow-monitor-module.h"
#include "ns3/stats-module.h"
#include "ns3/netanim-module.h"
//#include "ns3/random-variable.h"
#include "ns3/tap-bridge-module.h"
#include <algorithm> // std::sort
#include <vector>
// WiFi Start
#include <ctime>
#include "ns3/mobility-module.h"
#include "ns3/wifi-module.h"
//#include "wifi-example-apps.h"
// WiFi End
using namespace ns3;
//using namespace std;
NS_LOG_COMPONENT_DEFINE ("DashSimulation");
// LR Trace Start
int64_t l_packetDrops = 0;
uint64_t l_packetDropBytes = 0;
// flow monitor
FlowMonitorHelper flowmon_helper;
Ptr<FlowMonitor> monitor;
std::ofstream netStatsOut; // Create an output file stream (optional)
std::ofstream netHist; // Create an output file stream (optional)
/*
class NS3ElectricalModel {
public:
void Throughput ();
private:
};
*/
void LejlaThroughput () // in Mbps calculated every 0.5s
{
Ptr<Ipv4FlowClassifier> classifier=DynamicCast<Ipv4FlowClassifier>(flowmon_helper.GetClassifier());
std::string proto;
std::map< FlowId, FlowMonitor::FlowStats > stats = monitor->GetFlowStats();
netStatsOut << " Time: " << Simulator::Now ().GetSeconds () << std::endl;
for (std::map< FlowId, FlowMonitor::FlowStats>::iterator
flow=stats.begin(); flow!=stats.end(); flow++)
{
Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow(flow->first);
switch(t.protocol)
{
case(6):
proto = "TCP";
break;
case(17):
proto = "UDP";
break;
default:
exit(1);
}
netStatsOut << "FlowID: " << flow->first << " (" << proto << " "
<< t.sourceAddress << " / " << t.sourcePort << " --> "
<< t.destinationAddress << " / " << t.destinationPort << ")" << std::endl;
// printStats(flow->second);
netStatsOut << " Tx Bytes: " << flow->second.txBytes << std::endl;
netStatsOut << " Rx Bytes: " << flow->second.rxBytes << std::endl;
netStatsOut << " Tx Packets: " << flow->second.txPackets << std::endl;
netStatsOut << " Rx Packets: " << flow->second.rxPackets << std::endl;
netStatsOut << " Lost Packets: " << flow->second.lostPackets << std::endl;
netStatsOut << " Pkt Lost Ratio: " << ((double)flow->second.txPackets-(double)flow->second.rxPackets)/(double)flow->second.txPackets << std::endl;
netStatsOut << " Throughput: " << (( ((double)flow->second.rxBytes*8)/(1000000) ) / .5) << std::endl;
netStatsOut << " Mean{Delay}: " << (flow->second.delaySum.GetSeconds()/flow->second.rxPackets) << std::endl;
netStatsOut << " Mean{Jitter}: " << (flow->second.jitterSum.GetSeconds()/(flow->second.rxPackets)) << std::endl;
}
Simulator::Schedule (Seconds (.5), &LejlaThroughput); // Callback every 0.5s
}
void
printStats (FlowMonitor::FlowStats st) {
netHist << "Lost: " << st.lostPackets ;
netHist << " Rx: " << st.rxPackets << " Size: " << st.rxBytes;
if (st.rxPackets > 0)
{
//netHist << " " <<(st.jitterSum.GetSeconds() / (st.rxPackets-1)) ;
netHist << " Hop: " << st.timesForwarded / st.rxPackets + 1;
Time duration = (st.timeLastRxPacket - st.timeFirstRxPacket );
netHist << " T: "
<< duration.GetSeconds ();
// netHist << " Throughput: " << (( ((double)st.rxBytes*8)/(1000000) ) / .5) << std::endl;
netHist << " TP: " << (( ((double)st.rxBytes*8)/(1000) ) / (duration.GetSeconds ())) << std::endl;
}
for (uint32_t i=0; i<st.packetsDropped.size (); i++)
netHist << "**********Packets dropped by reason " << i << ": " << st.packetsDropped [i] << std::endl;
// for (uint32_t i=0; i<st.bytesDropped.size(); i++)
// std::cout << "Bytes dropped by reason " << i << ": " << st.bytesDropped[i] << std::endl;
//netHist << std::endl;
}
void
printStatsFull (FlowMonitor::FlowStats st) {
netHist << " Tx Bytes: " << st.txBytes << std::endl;
netHist << " Rx Bytes: " << st.rxBytes << std::endl;
netHist << " Tx Packets: " << st.txPackets << std::endl;
netHist << " Rx Packets: " << st.rxPackets << std::endl;
netHist << " Lost Packets: " << st.lostPackets << std::endl;
if (st.rxPackets > 0)
{
netHist << " Mean{Delay}: "
<< (st.delaySum.GetSeconds() / st.rxPackets) << std::endl;
netHist << " Mean{Jitter}: "
<< (st.jitterSum.GetSeconds() / (st.rxPackets-1)) << std::endl;
netHist << " Mean{Hop Count}: "
<< st.timesForwarded / st.rxPackets + 1 << std::endl;
Time duration = (st.timeLastRxPacket - st.timeFirstRxPacket );
netHist << " Time: "
<< duration.GetSeconds () << std::endl;
// netHist << " Throughput: " << (( ((double)st.rxBytes*8)/(1000000) ) / .5) << std::endl;
netHist << " Throughput: " << (( ((double)st.rxBytes*8)/(1000) ) / (duration.GetSeconds ())) << std::endl;
}
// if (false)
{
netHist << "***********Delay Histogram" << std::endl;
for (uint32_t i=0; i<st.delayHistogram.GetNBins (); i++)
netHist << " " << i << "(" << st.delayHistogram.GetBinStart (i) << "-"
<< st.delayHistogram.GetBinEnd (i) << "): "
<< st.delayHistogram.GetBinCount (i) << std::endl;
netHist << "***********Jitter Histogram" << std::endl;
for (uint32_t i=0; i<st.jitterHistogram.GetNBins (); i++ )
netHist << " " << i << "(" << st.jitterHistogram.GetBinStart (i) << "-"
<< st.jitterHistogram.GetBinEnd (i) << "): "
<< st.jitterHistogram.GetBinCount (i) << std::endl;
netHist << "**********PacketSize Histogram "<< std::endl;
for (uint32_t i=0; i<st.packetSizeHistogram.GetNBins (); i++ )
netHist << " " << i << "(" << st.packetSizeHistogram.GetBinStart (i) << "-"
<< st.packetSizeHistogram.GetBinEnd (i) << "): "
<< st.packetSizeHistogram.GetBinCount (i) << std::endl;
}
for (uint32_t i=0; i<st.packetsDropped.size (); i++)
netHist << "**********Packets dropped by reason " << i << ": " << st.packetsDropped [i] << std::endl;
// for (uint32_t i=0; i<st.bytesDropped.size(); i++)
// std::cout << "Bytes dropped by reason " << i << ": " << st.bytesDropped[i] << std::endl;
netHist << std::endl;
}
// end flow monitor
int
main (int argc, char *argv[])
{
GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));
GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
// Users may find it convenient to turn on explicit debugging
// for selected modules; the below lines suggest how to do this
PacketMetadata::Enable ();
LogComponentEnable ("DashSimulation", LOG_LEVEL_ALL); // prints simulation messages
uint32_t N = 3;
uint32_t nCsma = 3;// 20; //nCsma-1 learners
std::string trFile = "video"; //TCP dump, trace file
std::string tcpType = "Reno"; // TCP type
//std::string tcpType = "Tahoe"; // TCP type
// bool enableFlowMonitor = true;
// bool bgTraffic = false;
// Set up command line parameters used to control the experiment.
// Allow the user to override any of the defaults and the above
// Config::SetDefault()s at run-time, via command-line arguments
CommandLine cmd;
cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma);
cmd.AddValue ("nNodes", "Number of Servers", N);
cmd.Parse (argc, argv);
// Set the TCP Socket Type
Config::SetDefault ("ns3::TcpL4Protocol::SocketType", TypeIdValue(TypeId::LookupByName ("ns3::Tcp" + tcpType)));
nCsma = nCsma == 0 ? 1 : nCsma;
// Create 2 nodes.
NS_LOG_INFO ("Create nodes.");
NodeContainer p2pNodes;
p2pNodes.Create (2);
// Createl LAN nodes
NodeContainer csmaNodes;
csmaNodes.Add (p2pNodes.Get (1)); // on the local network
csmaNodes.Create (nCsma);
// reate proxy node
NodeContainer proxyNode;
proxyNode.Add (p2pNodes.Get (0)); // proxy
// crate Remote Host nodes
NodeContainer derNodes;
derNodes.Create (N);
//Collect an adjacency list of nodes for the p2p topology
std::vector<NodeContainer> derAdjacencyList (N);
// std::vector<NodeContainer> learnerAdjacencyList (M);
for(uint32_t i=0; i<derAdjacencyList.size (); ++i)
{
derAdjacencyList[i] = NodeContainer (proxyNode, derNodes.Get (i));
}
// crexate the channels without any IP addressing information
NS_LOG_INFO ("Create channels.");
PointToPointHelper p2p;
// set local routers
p2p.SetDeviceAttribute ("DataRate", StringValue ("100Mbps"));
p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
p2p.SetDeviceAttribute ("Mtu", UintegerValue (1500));
NetDeviceContainer p2pDevices;
p2pDevices = p2p.Install (p2pNodes);
//std::cout << "MTU P2P " << p2pNodes.Get(0)->GetDevice(0)->GetMtu() << std::endl;
NS_LOG_INFO("MTU P2P " << p2pNodes.Get(0)->GetDevice(0)->GetMtu());
//set local network
CsmaHelper csma;
csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));
NetDeviceContainer csmaDevices;
csmaDevices = csma.Install (csmaNodes);
// Use the TapBridgeHelper to connect to the pre-configured tap devices for
// the left side. We go with "UseBridge" mode since the CSMA devices support
// promiscuous mode and can therefore make it appear that the bridge is
// extended into ns-3. The install method essentially bridges the specified
// tap to the specified CSMA device.
TapBridgeHelper tapBridge;
tapBridge.SetAttribute ("Mode", StringValue ("UseBridge"));
tapBridge.SetAttribute ("DeviceName", StringValue ("tap-left"));
tapBridge.Install (csmaNodes.Get (0), csmaDevices.Get (0));
// set remote Servers
TimeValue val (Time("0ms"));
std::vector<NetDeviceContainer> derDeviceAdjacencyList (N);
for(uint32_t i=0; i<derDeviceAdjacencyList.size (); ++i)
{
std::ostringstream delaySt;
delaySt << 15 + (i) * 35 << "ms";
std::ostringstream dataRate;
dataRate << 15 - (i) * 3 << "Mbps";
val.Set(Time(delaySt.str())); // required for delays
p2p.SetDeviceAttribute ("DataRate", StringValue (dataRate.str()));
p2p.SetDeviceAttribute ("Mtu", UintegerValue (1500));
p2p.SetChannelAttribute ("Delay", val);
derDeviceAdjacencyList[i] = p2p.Install (derAdjacencyList[i]);
//csmaDevices = csma.Install (csmaNodes);
//std::cout << "MTU P2P " << p2pNodes.Get(0)->GetDevice(0)->GetMtu() << std::endl;
}
tapBridge.SetAttribute ("DeviceName", StringValue ("tap-right"));
tapBridge.Install (derNodes.Get (1), derDeviceAdjacencyList[1].Get(1));
// Install network stacks on the nodes
InternetStackHelper internet;
internet.Install (derNodes); // proxy node part of this
internet.Install (p2pNodes.Get (0));
internet.Install (csmaNodes);
// add IP addresses.
NS_LOG_INFO ("Assign IP Addresses.");
Ipv4AddressHelper ipv4;
std::vector<Ipv4InterfaceContainer> derInterfaceAdjacencyList (N);
for(uint32_t i=0; i<derInterfaceAdjacencyList.size (); ++i)
{
std::ostringstream subnet;
subnet<<"10.1."<<i<<".0";
NS_LOG_INFO (subnet.str ().c_str ());
ipv4.SetBase (subnet.str ().c_str (), "255.255.255.0");
derInterfaceAdjacencyList[i] = ipv4.Assign (derDeviceAdjacencyList[i]);
}
// local routers
ipv4.SetBase ("10.1.150.0", "255.255.255.0");
Ipv4InterfaceContainer p2pInterfaces;
p2pInterfaces = ipv4.Assign (p2pDevices);
// local nodes
ipv4.SetBase ("10.1.200.0", "255.255.255.0");
Ipv4InterfaceContainer csmaInterfaces;
csmaInterfaces = ipv4.Assign (csmaDevices);
//Turn on global static routing
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
NS_LOG_INFO("Create Learner Application.");
uint16_t port = 50001;
// Create the OnOff applications to send TCP to the servers
OnOffHelper clientHelper ("ns3::TcpSocketFactory", Address ());
clientHelper.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
clientHelper.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
NS_LOG_INFO ("Create clients.");
//normally wouldn't need a loop here but the server IP address is different
//on each p2p subnet
ApplicationContainer clientApps;
for(uint32_t i=0; i<nCsma; ++i)
{
AddressValue remoteAddress
(InetSocketAddress (derInterfaceAdjacencyList[i].GetAddress (1), port));
clientHelper.SetAttribute ("Remote", remoteAddress);
clientApps.Add (clientHelper.Install (csmaNodes.Get (i)));
}
clientApps.Start (Seconds (1.0));
clientApps.Stop (Seconds (10.0));
NS_LOG_INFO("Create DER Applications.");
// currently all DERs have the same settings
PacketSinkHelper sinkHelper("ns3::TcpSocketFactory", Address ());
ApplicationContainer derApps;
for(uint32_t i=0; i<derInterfaceAdjacencyList.size (); ++i)
{
Address derLocalAddress (InetSocketAddress (derInterfaceAdjacencyList[i].GetAddress (1), port));
PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory", derLocalAddress);
derApps.Add (clientHelper.Install (derNodes.Get (i)));
}
derApps.Start (Seconds (1.0));
derApps.Stop (Seconds (10.0));
NS_LOG_INFO ("Run Simulation.");
Simulator::Stop(Seconds(25.0));
AsciiTraceHelper ascii;
p2p.EnableAsciiAll (ascii.CreateFileStream ("traceL.tr"));
p2p.EnablePcapAll ("tcppcap");
//AnimationInterface anim ("Topology.xml");
//anim.SetConstantPosition (p2pNodes.Get(0), 1.0, 3.0);
//anim.SetConstantPosition (csmaNodes.Get(0), 3.0, 3.0);
//anim.SetConstantPosition (csmaNodes.Get(1), 4.0, 4.0);
//anim.SetConstantPosition (csmaNodes.Get(2), 4.0, 3.0);
//anim.SetConstantPosition (csmaNodes.Get(3), 4.0, 2.0);
// anim.SetConstantPosition (derNodes.Get (0), 0.0, 2.0);
// anim.SetConstantPosition (derNodes.Get (1), 0.0, 3.0);
//anim.SetConstantPosition (derNodes.Get (2), 0.0, 4.0);
Simulator::Run ();
Simulator::Destroy ();
NS_LOG_INFO ("********************** Done ***************************");
return 0;
}
This is happening because you are trying to use the TapBridge in
'UseBridge' mode with a PointToPointNetDevice, which doesn't support
bridging.
Some documentation about the different modes is here:
https://www.nsnam.org/docs/models/html/tap.html#
I recommend reconfiguring your topology a bit (even if you have to
insert an additional node/LAN) so that you can instead bind a Csma
device to this tap bridge. I don't think PointToPoint will work well
because it is not a device type that uses 48-bit MAC addresses.
- Tom