54 InternetStackHelper stack;
55 stack.SetIpv4StackInstall(v4);
56 stack.SetIpv6StackInstall(v6);
58 Ipv6ListRoutingHelper list6;
69 InternetStackHelper custom;
70 custom.SetIpv4StackInstall(v4);
71 custom.SetIpv6StackInstall(v6);
72 custom.SetRoutingHelper(list6);
78 InternetStackHelper stack;
79 stack.SetIpv4StackInstall(v4);
80 stack.SetIpv6StackInstall(v6);
117 PointToPointHelper p2p;
118 p2p.SetDeviceAttribute(
"DataRate", StringValue(
m_defRate));
119 p2p.SetChannelAttribute(
"Delay", StringValue(
m_defDelay));
121 Ipv4AddressHelper v4h;
122 v4h.SetBase(
"10.1.0.0",
"255.255.0.0");
123 Ipv6AddressHelper v6h;
124 v6h.SetBase(Ipv6Address(
"2001:db8::"), Ipv6Prefix(64));
126 for (
const auto& l :
m_links) {
127 Ptr<Node> A =
m_nodes.at(l.nodeA);
128 Ptr<Node> B =
m_nodes.at(l.nodeB);
129 NetDeviceContainer devs = p2p.Install(A, B);
131 auto& aEntry = handle.
nodes[l.nodeA];
132 auto& bEntry = handle.
nodes[l.nodeB];
133 aEntry.devices.push_back(devs.Get(0));
134 bEntry.devices.push_back(devs.Get(1));
135 aEntry.devBySegment[l.id] = devs.Get(0);
136 bEntry.devBySegment[l.id] = devs.Get(1);
138 Ipv4InterfaceContainer if4;
139 Ipv6InterfaceContainer if6;
143 if4 = v4h.Assign(devs);
144 aEntry.v4Addrs.push_back(if4.GetAddress(0));
145 bEntry.v4Addrs.push_back(if4.GetAddress(1));
149 if6 = v6h.Assign(devs);
150 if6.SetForwarding(0,
true);
151 if6.SetForwarding(1,
true);
153 if6.SetDefaultRouteInAllNodes(0);
154 if6.SetDefaultRouteInAllNodes(1);
156 aEntry.v6Addrs.push_back(if6.GetAddress(0, 1));
157 bEntry.v6Addrs.push_back(if6.GetAddress(1, 1));
161 auto& ai = aEntry.segIf[l.id];
162 auto& bi = bEntry.segIf[l.id];
164 ai.ifIndexV4 = A->GetObject<Ipv4>()->GetInterfaceForDevice(devs.Get(0));
165 bi.ifIndexV4 = B->GetObject<Ipv4>()->GetInterfaceForDevice(devs.Get(1));
166 ai.v4 = if4.GetAddress(0);
167 bi.v4 = if4.GetAddress(1);
170 ai.ifIndexV6 = A->GetObject<Ipv6>()->GetInterfaceForDevice(devs.Get(0));
171 bi.ifIndexV6 = B->GetObject<Ipv6>()->GetInterfaceForDevice(devs.Get(1));
172 ai.v6 = if6.GetAddress(0, 1);
173 bi.v6 = if6.GetAddress(1, 1);
174 ai.v6ll = if6.GetAddress(0, 0);
175 bi.v6ll = if6.GetAddress(1, 0);
181 for (
const auto& lan :
m_lans) {
183 csma.SetChannelAttribute(
"DataRate", StringValue(lan.rate.empty() ?
m_defRate : lan.rate));
184 csma.SetChannelAttribute(
"Delay", StringValue(lan.delay.empty() ?
m_defDelay : lan.delay));
186 NodeContainer members;
187 for (
auto& name : lan.members)
190 NetDeviceContainer devs = csma.Install(members);
192 Ipv4AddressHelper v4h;
193 v4h.SetBase(
"10.1.0.0",
"255.255.0.0");
194 Ipv6AddressHelper v6h;
195 v6h.SetBase(Ipv6Address(
"2001:db8:1::"), Ipv6Prefix(64));
197 Ipv4InterfaceContainer if4;
198 Ipv6InterfaceContainer if6;
201 if4 = v4h.Assign(devs);
202 for (uint32_t i = 0; i < members.GetN(); ++i) {
203 auto name = lan.members[i];
204 handle.
nodes[name].devices.push_back(devs.Get(i));
205 handle.
nodes[name].v4Addrs.push_back(if4.GetAddress(i));
206 handle.
nodes[name].ifaceIndex.push_back(
207 members.Get(i)->GetObject<Ipv4>()->GetInterfaceForDevice(devs.Get(i)));
208 handle.
nodes[name].devBySegment[lan.id] = devs.Get(i);
210 auto& info4 = handle.
nodes[name].segIf[lan.id];
211 info4.ifIndexV4 = members.Get(i)->GetObject<Ipv4>()->GetInterfaceForDevice(devs.Get(i));
212 info4.v4 = if4.GetAddress(i);
216 if6 = v6h.Assign(devs);
217 for (uint32_t i = 0; i < members.GetN(); ++i) {
218 auto name = lan.members[i];
219 if6.SetForwarding(i,
true);
221 if6.SetDefaultRouteInAllNodes(i);
223 handle.
nodes[name].devices.push_back(devs.Get(i));
224 handle.
nodes[name].v6Addrs.push_back(if6.GetAddress(i, 1));
225 handle.
nodes[name].ifaceIndex.push_back(
226 members.Get(i)->GetObject<Ipv6>()->GetInterfaceForDevice(devs.Get(i)));
227 handle.
nodes[name].devBySegment[lan.id] = devs.Get(i);
229 auto& info6 = handle.
nodes[name].segIf[lan.id];
230 info6.ifIndexV6 = members.Get(i)->GetObject<Ipv6>()->GetInterfaceForDevice(devs.Get(i));
231 info6.v6 = if6.GetAddress(i, 1);
232 info6.v6ll = if6.GetAddress(i, 0);
240 std::map<std::string, std::vector<std::string>> segMembers;
241 for (
const auto& [name, entry] : h.
nodes)
242 for (
const auto& kv : entry.segIf)
243 segMembers[kv.first].push_back(name);
246 std::map<std::string, std::vector<std::string>> adj;
247 for (
const auto& [seg, members] : segMembers) {
248 if (members.size() < 2)
250 if (members.size() == 2) {
251 adj[members[0]].push_back(members[1]);
252 adj[members[1]].push_back(members[0]);
254 for (
size_t i = 0; i < members.size(); ++i)
255 for (
size_t j = i + 1; j < members.size(); ++j) {
256 adj[members[i]].push_back(members[j]);
257 adj[members[j]].push_back(members[i]);
262 Ipv4StaticRoutingHelper v4h;
263 Ipv6StaticRoutingHelper v6h;
265 for (
const auto& [srcName, srcEntry] : h.
nodes) {
267 std::unordered_map<std::string, std::string> parent;
268 std::queue<std::string> q;
269 parent[srcName] =
"";
273 std::string u = q.front();
275 for (
const auto& v : adj[u]) {
276 if (!parent.count(v)) {
283 auto firstHop = [&](
const std::string& dst) -> std::string {
286 if (!parent.count(dst))
288 std::string cur = dst, prev = parent.at(cur);
289 while (!prev.empty() && prev != srcName) {
291 prev = parent.at(cur);
293 return prev.empty() ? std::string() : cur;
297 for (
const auto& [dstName, dstEntry] : h.
nodes) {
298 if (dstName == srcName)
300 std::string nhName = firstHop(dstName);
306 for (
const auto& kv : srcEntry.segIf) {
307 if (h.
nodes.at(nhName).segIf.count(kv.first)) {
315 const auto& meSeg = srcEntry.segIf.at(segId);
316 const auto& nhSeg = h.
nodes.at(nhName).segIf.at(segId);
318 if (h.
hasIpv4 && !dstEntry.v4Addrs.empty() && meSeg.ifIndexV4 != UINT32_MAX &&
319 nhSeg.ifIndexV4 != UINT32_MAX) {
320 auto me4 = srcEntry.node->GetObject<Ipv4>();
321 auto rt = v4h.GetStaticRouting(me4);
322 rt->AddHostRouteTo(dstEntry.v4Addrs.front(), nhSeg.v4, meSeg.ifIndexV4);
325 if (h.
hasIpv6 && !dstEntry.v6Addrs.empty() && meSeg.ifIndexV6 != UINT32_MAX &&
326 nhSeg.ifIndexV6 != UINT32_MAX) {
327 auto me6 = srcEntry.node->GetObject<Ipv6>();
328 auto rt6 = v6h.GetStaticRouting(me6);
329 rt6->AddHostRouteTo(dstEntry.v6Addrs.front(), nhSeg.v6ll, meSeg.ifIndexV6);