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<

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);

    }
 
  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








posted @ 2016-08-31 20:43  张同光  阅读(184)  评论(0编辑  收藏  举报