Skip to content

Commit

Permalink
nix-vector-routing: Handle Multiple Wifi connections with same channe…
Browse files Browse the repository at this point in the history
…l object

Signed-off-by: Ameya Deshpande <[email protected]>
  • Loading branch information
ameyanrd authored and TommyPec committed Aug 26, 2021
1 parent 2d512ad commit 7be8710
Show file tree
Hide file tree
Showing 9 changed files with 406 additions and 14 deletions.
3 changes: 2 additions & 1 deletion CHANGES.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ <h2>New API:</h2>
<li>In class <b>Ipv6Header</b>, new functions SetSource (), SetDestination (), GetSource () and GetDestination () are added, consistent with <b>Ipv4Header</b>. The existing functions had "Address" suffix in each of the function names, and are are deprecated now.</li>
<li>In class <b>Ipv4InterfaceAddress</b>, new functions SetAddress () and GetAddress () are added, corresponding to SetLocal () and GetLocal () respectively. This is done to keep consistency with <b>Ipv4InterfaceAddress</b>.</li>
<li>With the new support for IPv6 Nix-Vector routing, we have all the new APIs corresponding to IPv4 Nix-Vector routing. Specific to the user, there is an Ipv6NixVectorHelper class which can be set in the InternetStackHelper, and works similar to Ipv4NixVectorHelper.</li>
<li>In class <b>Ipv4InterfaceAddress</b>, a new function IsInSameSubnet () is added to check if both the IPv4 addresses are in the same subnet. Also, it is consistent with <b>Ipv6InterfaceAddress::IsInSameSubnet ()</b>.</li>
</ul>
<h2>Changes to existing API:</h2>
<ul>
Expand All @@ -69,7 +70,7 @@ <h2>Changes to build system:</h2>
</ul>
<h2>Changed behavior:</h2>
<ul>
<li></li>
<li>Nix-Vector routing supports topologies with multiple WiFi networks using the same WiFi channel object.</li>
</ul>

<hr>
Expand Down
4 changes: 3 additions & 1 deletion RELEASE_NOTES
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ requirements (Note: not all ns-3 features are available on all systems):
New user-visible features
-------------------------
- (internet) Added getters and setters for source and destination in Ipv6Header consistent with Ipv4Header naming.
- (internet) Add new functions SetAddress () and GetAddress () are added, corresponding to SetLocal () and GetLocal () respectively in Ipv4InterfaceAddress to keep consistency with Ipv6InterfaceAddress.
- (internet) New functions SetAddress () and GetAddress () are added, corresponding to SetLocal () and GetLocal () respectively in Ipv4InterfaceAddress to keep consistency with Ipv6InterfaceAddress.
- (nix-vector-routing) Support for IPv6 Nix-Vector routing. Existing nix-simple and nms-p2p-nix examples are available in IPv6 as well.
- (nix-vector-routing) ipv4-nix-vector-helper.h has been deprecated in favour of nix-vector-helper.h.
- (nix-vector-routing) ipv4-nix-vector-routing.h has been deprecated in favour of nix-vector-routing.h.
- (internet) Added new function IsInSameSubnet () in Ipv4InterfaceAddress similar to Ipv6InterfaceAddress::IsInSameSubnet (). It checks if the two Ipv4Address are in the same subnet.
- (nix-vector-routing) Nix-Vector routing supports topologies with multiple WiFi networks using the same WiFi channel object.
Bugs fixed
----------

Expand Down
10 changes: 10 additions & 0 deletions src/internet/model/ipv4-interface-address.cc
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,16 @@ Ipv4InterfaceAddress::GetScope (void) const
return m_scope;
}

bool Ipv4InterfaceAddress::IsInSameSubnet (const Ipv4Address b) const
{
Ipv4Address aAddr = m_local;
aAddr = aAddr.CombineMask(m_mask);
Ipv4Address bAddr = b;
bAddr = bAddr.CombineMask(m_mask);

return (aAddr == bAddr);
}

bool
Ipv4InterfaceAddress::IsSecondary (void) const
{
Expand Down
7 changes: 7 additions & 0 deletions src/internet/model/ipv4-interface-address.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,13 @@ class Ipv4InterfaceAddress
*/
Ipv4InterfaceAddress::InterfaceAddressScope_e GetScope (void) const;

/**
* \brief Checks if the address is in the same subnet.
* \param b the address to check
* \return true if the address is in the same subnet.
*/
bool IsInSameSubnet (const Ipv4Address b) const;

/**
* \brief Check if the address is a secondary address
*
Expand Down
41 changes: 31 additions & 10 deletions src/nix-vector-routing/doc/nix-vector-routing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,14 @@ Scope and Limitations
=====================

Currently, the |ns3| model of nix-vector routing supports IPv4 and IPv6
p2p links as well as CSMA links. It does not (yet) provide support for
efficient adaptation to link failures. It simply flushes all nix-vector
routing caches.
p2p links, CSMA links and multiple WiFi networks with the same channel object.
It does not (yet) provide support for efficient adaptation to link failures.
It simply flushes all nix-vector routing caches.

NixVectorRouting bases its routing decisions on the nodes' interface
addresses and does **not** check whether the nodes are in the proper
subnets or the addresses have been appropriately assigned. In other
terms, using Nix-Vector routing, it is possible to have a working
network that violates every good practice in IP address assignments.
NixVectorRouting performs a subnet matching check, but it does **not** check
entirely if the addresses have been appropriately assigned. In other terms,
using Nix-Vector routing, it is possible to have a working network that
violates some good practices in IP address assignments.

In case of IPv6, Nix assumes the link-local addresses assigned are **unique**.
When using the IPv6 stack, the link-local address allocation is unique by
Expand Down Expand Up @@ -177,7 +176,7 @@ Thus, the nix-vector for the path from n0 to n3 is 101.
#. Using IPv6:
.. code-block:: bash
# Set ip as "v6" explicity
# Use the --useIPv6 flag
./waf --run "src/nix-vector-routing/examples/nix-simple --useIPv6"
* nms-p2p-nix.cc
Expand All @@ -197,7 +196,7 @@ performs source-based routing (BFS) to have faster routing.
#. Using IPv6:
.. code-block:: bash

# Set ip as "v6" explicity
# Use the --useIPv6 flag
./waf --run "src/nix-vector-routing/examples/nms-p2p-nix --useIPv6"

* nix-simple-multi-address.cc
Expand All @@ -210,3 +209,25 @@ the all the route caches and Nix caches to flush.
# By default IPv4 network is selected
./waf --run src/nix-vector-routing/examples/nix-simple-multi-address
* nix-double-wifi.cc

This example demonstrates the working of Nix with two Wifi networks
operating on the same Wifi channel object. The example uses ``ns3::YansWifiChannel``
for both the wifi networks.

#. Using IPv4:
.. code-block:: bash
# By default IPv4 network is selected
./waf --run src/nix-vector-routing/examples/nix-double-wifi
# Use the --enableNixLog to enable NixVectorRouting logging.
./waf --run "src/nix-vector-routing/examples/nix-double-wifi --enableNixLog"
#. Using IPv6:
.. code-block:: bash
# Use the --useIPv6 flag
./waf --run "src/nix-vector-routing/examples/nix-double-wifi --useIPv6"
# Use the --enableNixLog to enable NixVectorRouting logging.
./waf --run "src/nix-vector-routing/examples/nix-double-wifi --useIPv6 --enableNixLog"
262 changes: 262 additions & 0 deletions src/nix-vector-routing/examples/nix-double-wifi.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2021 NITK Surathkal
*
* 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
*
* This example is inspired from examples/tutorial/third.cc by
* substituting the CSMA network with another WiFi network.
*
* Author: Ameya Deshpande <[email protected]>
*/

#include "ns3/core-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/network-module.h"
#include "ns3/applications-module.h"
#include "ns3/mobility-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/wifi-module.h"
#include "ns3/ssid.h"
#include "ns3/nix-vector-routing-module.h"

/**
* This example demonstrates how Nix works with
* two Wifi networks on the same channel.
*
* IPv4 Network Topology
* \verbatim
Wifi 10.1.1.0/24
AP
* * * *
| | | | 10.1.2.0/24
n5 n6 n7 n0 -------------- n1 n2 n3 n4
point-to-point | | | |
* * * *
AP
Wifi 10.1.3.0/24
\endverbatim
*
* \verbatim
Wifi 2001:1::/64
AP
* * * *
| | | | 2001:2::/64
n5 n6 n7 n0 -------------- n1 n2 n3 n4
point-to-point | | | |
* * * *
AP
Wifi 2001:3::/64
\endverbatim
*
* Expected Outputs:
* IPv4:
* \verbatim
Time: +7s, Nix Routing
Route Path: (Node 4 to Node 7, Nix Vector: 100011)
10.1.1.3 (Node 4) ----> 10.1.1.4 (Node 0)
10.1.2.1 (Node 0) ----> 10.1.2.2 (Node 1)
10.1.3.4 (Node 1) ----> 10.1.3.3 (Node 7)
\endverbatim
*
* IPv6:
* \verbatim
Time: +7s, Nix Routing
Route Path: (Node 4 to Node 7, Nix Vector: 100011)
2001:1::200:ff:fe00:5 (Node 4) ----> fe80::200:ff:fe00:6 (Node 0)
fe80::200:ff:fe00:1 (Node 0) ----> fe80::200:ff:fe00:2 (Node 1)
fe80::200:ff:fe00:a (Node 1) ----> 2001:3::200:ff:fe00:9 (Node 7)
\endverbatim
*/

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("NixDoubleWifiExample");

int
main (int argc, char *argv[])
{
bool useIpv6 = false;
bool enableNixLog = false;

CommandLine cmd (__FILE__);
cmd.AddValue ("useIPv6", "Use IPv6 instead of IPv4", useIpv6);
cmd.AddValue ("enableNixLog", "Enable NixVectorRouting logging", enableNixLog);
cmd.Parse (argc,argv);

LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
if (enableNixLog)
{
LogComponentEnable ("NixVectorRouting", LOG_LEVEL_LOGIC);
}

NodeContainer p2pNodes;
p2pNodes.Create (2);

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));

NetDeviceContainer p2pDevices;
p2pDevices = pointToPoint.Install (p2pNodes);

NodeContainer wifiStaNodes1;
wifiStaNodes1.Create (3);
NodeContainer wifiApNode1 = p2pNodes.Get (0);

NodeContainer wifiStaNodes2;
wifiStaNodes2.Create (3);
NodeContainer wifiApNode2 = p2pNodes.Get (1);

YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
YansWifiPhyHelper phy;
phy.SetChannel (channel.Create ());

WifiHelper wifi;
wifi.SetRemoteStationManager ("ns3::AarfWifiManager");

WifiMacHelper mac;
Ssid ssid = Ssid ("ns-3-ssid-first");
mac.SetType ("ns3::StaWifiMac",
"Ssid", SsidValue (ssid),
"ActiveProbing", BooleanValue (false));

NetDeviceContainer staDevices1;
staDevices1 = wifi.Install (phy, mac, wifiStaNodes1);

mac.SetType ("ns3::ApWifiMac",
"Ssid", SsidValue (ssid));

NetDeviceContainer apDevices1;
apDevices1 = wifi.Install (phy, mac, wifiApNode1);

ssid = Ssid ("ns-3-ssid-second");
mac.SetType ("ns3::StaWifiMac",
"Ssid", SsidValue (ssid),
"ActiveProbing", BooleanValue (false));

NetDeviceContainer staDevices2;
staDevices2 = wifi.Install (phy, mac, wifiStaNodes2);

mac.SetType ("ns3::ApWifiMac",
"Ssid", SsidValue (ssid));

NetDeviceContainer apDevices2;
apDevices2 = wifi.Install (phy, mac, wifiApNode2);

MobilityHelper mobility;

mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
"MinX", DoubleValue (0.0),
"MinY", DoubleValue (0.0),
"DeltaX", DoubleValue (5.0),
"DeltaY", DoubleValue (10.0),
"GridWidth", UintegerValue (3),
"LayoutType", StringValue ("RowFirst"));

mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel",
"Bounds", RectangleValue (Rectangle (-50, 50, -50, 50)));
mobility.Install (wifiStaNodes1);
mobility.Install (wifiStaNodes2);

mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (wifiApNode1);
mobility.Install (wifiApNode2);

Address udpServerAddress;

if (!useIpv6)
{
InternetStackHelper stack;
Ipv4NixVectorHelper nixRouting;
stack.SetRoutingHelper (nixRouting);
stack.Install (wifiApNode1);
stack.Install (wifiStaNodes1);
stack.Install (wifiApNode2);
stack.Install (wifiStaNodes2);

Ipv4AddressHelper address;

address.SetBase ("10.1.1.0", "255.255.255.0");
address.Assign (staDevices1);
address.Assign (apDevices1);

address.SetBase ("10.1.2.0", "255.255.255.0");
Ipv4InterfaceContainer p2pInterfaces;
p2pInterfaces = address.Assign (p2pDevices);

address.SetBase ("10.1.3.0", "255.255.255.0");
Ipv4InterfaceContainer staDevicesInterfaces2;
staDevicesInterfaces2 = address.Assign (staDevices2);
address.Assign (apDevices2);

udpServerAddress = staDevicesInterfaces2.GetAddress (2);

Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("nix-double-wifi-ipv4.routes", std::ios::out);
nixRouting.PrintRoutingPathAt (Seconds (7), wifiStaNodes1.Get (2), staDevicesInterfaces2.GetAddress (2), routingStream);
}
else
{
InternetStackHelper stack;
Ipv6NixVectorHelper nixRouting;
stack.SetRoutingHelper (nixRouting);
stack.Install (wifiApNode1);
stack.Install (wifiStaNodes1);
stack.Install (wifiApNode2);
stack.Install (wifiStaNodes2);

Ipv6AddressHelper address;

address.SetBase (Ipv6Address ("2001:1::"), Ipv6Prefix (64));
address.Assign (staDevices1);
address.Assign (apDevices1);

address.SetBase (Ipv6Address ("2001:2::"), Ipv6Prefix (64));
Ipv6InterfaceContainer p2pInterfaces;
p2pInterfaces = address.Assign (p2pDevices);

address.SetBase (Ipv6Address ("2001:3::"), Ipv6Prefix (64));
Ipv6InterfaceContainer staDevicesInterfaces2;
staDevicesInterfaces2 = address.Assign (staDevices2);
address.Assign (apDevices2);

udpServerAddress = staDevicesInterfaces2.GetAddress (2, 1);

Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("nix-double-wifi-ipv6.routes", std::ios::out);
nixRouting.PrintRoutingPathAt (Seconds (7), wifiStaNodes1.Get (2), staDevicesInterfaces2.GetAddress (2, 1), routingStream);
}

UdpEchoServerHelper echoServer (9);

ApplicationContainer serverApps = echoServer.Install (wifiStaNodes2.Get (2));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));

UdpEchoClientHelper echoClient (udpServerAddress, 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));

ApplicationContainer clientApps = echoClient.Install (wifiStaNodes1.Get (2));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));

Simulator::Stop (Seconds (10.0));

Simulator::Run ();
Simulator::Destroy ();
return 0;
}
Loading

0 comments on commit 7be8710

Please sign in to comment.