Loading...
Searching...
No Matches
satellite-isl-arbiter-unicast-helper.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2013 Magister Solutions Ltd
4 * Copyright (c) 2018 CNES
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation;
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * Inspired and adapted from Hypatia: https://github.com/snkas/hypatia
20 *
21 * Author: Bastien Tauran <bastien.tauran@viveris.fr>
22 */
23
25
26#include "ns3/node-container.h"
27#include "ns3/node.h"
28#include "ns3/satellite-topology.h"
29#include "ns3/singleton.h"
30
31#include <map>
32#include <utility>
33#include <vector>
34
35NS_LOG_COMPONENT_DEFINE("SatIslArbiterUnicastHelper");
36
37namespace ns3
38{
39
40NS_OBJECT_ENSURE_REGISTERED(SatIslArbiterUnicastHelper);
41
42TypeId
44{
45 static TypeId tid = TypeId("ns3::SatIslArbiterUnicastHelper")
46 .SetParent<Object>()
47 .AddConstructor<SatIslArbiterUnicastHelper>();
48 return tid;
49}
50
52{
53 NS_FATAL_ERROR("Default constructor not in use");
54}
55
57 std::vector<std::pair<uint32_t, uint32_t>> isls)
58 : m_isls(isls)
59{
60 NS_LOG_FUNCTION(this);
61}
62
63void
65{
66 NS_LOG_FUNCTION(this);
67
68 std::vector<std::map<uint32_t, uint32_t>> globalState = CalculateGlobalState();
69
70 for (uint32_t satIndex = 0; satIndex < globalState.size(); satIndex++)
71 {
72 Ptr<Node> satelliteNode = Singleton<SatTopology>::Get()->GetOrbiterNode(satIndex);
73 Ptr<SatOrbiterNetDevice> satelliteOrbiterNetDevice;
74 for (uint32_t ndIndex = 0; ndIndex < satelliteNode->GetNDevices(); ndIndex++)
75 {
76 Ptr<SatOrbiterNetDevice> nd =
77 DynamicCast<SatOrbiterNetDevice>(satelliteNode->GetDevice(ndIndex));
78 if (nd != nullptr)
79 {
80 satelliteOrbiterNetDevice = nd;
81 }
82 }
83
84 NS_ASSERT_MSG(satelliteOrbiterNetDevice != nullptr,
85 "SatOrbiterNetDevice not found on satellite");
86
87 std::vector<Ptr<PointToPointIslNetDevice>> islNetDevices =
88 satelliteOrbiterNetDevice->GetIslsNetDevices();
89 Ptr<SatIslArbiterUnicast> arbiter = CreateObject<SatIslArbiterUnicast>(satelliteNode);
90
91 for (uint32_t islInterfaceIndex = 0; islInterfaceIndex < islNetDevices.size();
92 islInterfaceIndex++)
93 {
94 uint32_t interfaceNextHopNodeId =
95 islNetDevices[islInterfaceIndex]->GetDestinationNode()->GetId();
96 for (std::map<uint32_t, uint32_t>::iterator it = globalState[satIndex].begin();
97 it != globalState[satIndex].end();
98 it++)
99 {
100 uint32_t destinationNodeId = it->first;
101 uint32_t nextHopNodeId = it->second;
102
103 if (interfaceNextHopNodeId == nextHopNodeId)
104 {
105 arbiter->AddNextHopEntry(destinationNodeId, islInterfaceIndex);
106 }
107 }
108 }
109 satelliteOrbiterNetDevice->SetArbiter(arbiter);
110 }
111}
112
113void
115{
116 NS_LOG_FUNCTION(this);
117
118 this->InstallArbiters();
119}
120
121std::vector<std::map<uint32_t, uint32_t>>
123{
124 NS_LOG_FUNCTION(this);
125
126 // Final result
127 std::vector<std::vector<std::vector<uint32_t>>> globalCandidateList;
128
130 // Floyd-Warshall
131
132 int64_t n = Singleton<SatTopology>::Get()->GetNOrbiterNodes();
133
134 // Enforce that more than 40000 nodes is not permitted (sqrt(2^31) ~= 46340, so let's call it an
135 // even 40000)
136 if (n > 40000)
137 {
138 NS_FATAL_ERROR("Cannot handle more than 40000 nodes");
139 }
140
141 // Initialize with 0 distance to itself, and infinite distance to all others
142 int32_t n2 = n * n;
143 int32_t* dist = new int32_t[n2];
144 for (int i = 0; i < n; i++)
145 {
146 for (int j = 0; j < n; j++)
147 {
148 if (i == j)
149 {
150 dist[n * i + j] = 0;
151 }
152 else
153 {
154 dist[n * i + j] = 100000000;
155 }
156 }
157 }
158
159 // If there is an edge, the distance is 1
160 for (std::pair<uint64_t, uint64_t> edge : m_isls)
161 {
162 dist[n * edge.first + edge.second] = 1;
163 dist[n * edge.second + edge.first] = 1;
164 }
165
166 // Floyd-Warshall core
167 for (int k = 0; k < n; k++)
168 {
169 for (int i = 0; i < n; i++)
170 {
171 for (int j = 0; j < n; j++)
172 {
173 if (dist[n * i + j] > dist[n * i + k] + dist[n * k + j])
174 {
175 dist[n * i + j] = dist[n * i + k] + dist[n * k + j];
176 }
177 }
178 }
179 }
180
182 // Determine from the shortest path distances
183 // the possible next hops
184
185 // ECMP candidate list: candidate_list[current][destination] = [ list of next hops ]
186 globalCandidateList.reserve(n);
187 for (int i = 0; i < n; i++)
188 {
189 std::vector<std::vector<uint32_t>> v;
190 v.reserve(n);
191 for (int j = 0; j < n; j++)
192 {
193 v.push_back(std::vector<uint32_t>());
194 }
195 globalCandidateList.push_back(v);
196 }
197
198 // Candidate next hops are determined in the following way:
199 // For each edge a -> b, for a destination t:
200 // If the shortest_path_distance(b, t) == shortest_path_distance(a, t) - 1
201 // then a -> b must be part of a shortest path from a towards t.
202 for (std::pair<uint64_t, uint64_t> edge : m_isls)
203 {
204 for (int j = 0; j < n; j++)
205 {
206 if (dist[edge.first * n + j] - 1 == dist[edge.second * n + j])
207 {
208 globalCandidateList[edge.first][j].push_back(edge.second);
209 }
210 if (dist[edge.second * n + j] - 1 == dist[edge.first * n + j])
211 {
212 globalCandidateList[edge.second][j].push_back(edge.first);
213 }
214 }
215 }
216
217 // Free up the distance matrix
218 delete[] dist;
219
220 std::vector<std::map<uint32_t, uint32_t>> returnList;
221 for (uint32_t i = 0; i < globalCandidateList.size(); i++)
222 {
223 returnList.push_back(std::map<uint32_t, uint32_t>());
224 std::vector<std::vector<uint32_t>> v = globalCandidateList[i];
225 for (uint32_t j = 0; j < v.size(); j++)
226 {
227 if (v[j].size() > 0)
228 {
229 returnList[i].insert(
230 std::make_pair(j, v[j][0])); // TODO for ECMP, keep all values in v[j]
231 }
232 }
233 }
234
235 // Return the final global candidate list
236 return returnList;
237}
238
239} // namespace ns3
std::vector< std::pair< uint32_t, uint32_t > > m_isls
void InstallArbiters()
Install arbiter on all satellite nodes.
void UpdateArbiters()
Update arbiter on all satellite nodes.
std::vector< std::map< uint32_t, uint32_t > > CalculateGlobalState()
Compute routing tables for all satellite nodes.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.