Skip to content

ipv6tunneling: keep each tunnel interface on a link of its own - #1290

Open
adamgeorge309 wants to merge 1 commit into
masterfrom
topic/gy/ipv6-tunnel-not-wireless
Open

adamgeorge309 wants to merge 1 commit into
masterfrom
topic/gy/ipv6-tunnel-not-wireless

Conversation

@adamgeorge309

@adamgeorge309 adamgeorge309 commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Ipv6NetworkConfigurator linked every two Ipv6TunnelInterface modules of a network as members of one wireless local area network (LAN), because the module declared no isWireless parameter. With two tunnels, a border router got a route to its own tunnel exit point through the tunnel and encapsulated each packet again while simulation time stood still. The interface now declares isWireless = default(false), as TunInterface does. Results change only in networks that have two or more Ipv6TunnelInterface modules when a network configurator runs (Ipv6NetworkConfigurator, and also Ipv4NetworkConfigurator and NextHopNetworkConfigurator, which share the topology extraction); no shipped example, showcase, tutorial or fingerprint configuration has that.

Closes #1289

The problem

RFC (Request for Comments) 2473 (Generic Packet Tunneling in IPv6) Section 3 models a tunnel as a point-to-point virtual link between its two endpoints, and Ipv6Tunnel marks the interface point-to-point. NetworkInterface::initialize() (src/inet/networklayer/common/NetworkInterface.cc:121-124) classifies an interface without phys gates as wireless unless the module declares isWireless. L3NetworkConfiguratorBase::extractTopology() then links every pair of wireless interfaces that share a wireless identifier, and getWirelessId() returns "default" for an interface without a radio that no <wireless> element of the configuration names. That grouping is right for wireless interfaces; the tunnel interface was the one misclassified.

The new test tests/module/IPv6_tunnel_configurator_routes.test builds hostA - borderA - transitA - transitB - borderB - hostB, with a tunnel each way between the border routers and a manual route on each that sends the far host's prefix into its tunnel. The configurator computes all other routes, and each host sends 4 User Datagram Protocol (UDP) packets.

master 93210f4 this branch
borderB route for 2001:db8:2::/64, which holds the tunnel exit point 2001:db8:2::1 via fe80:: dev tun0, ahead of the route via eth0 via eth0 only
end of the run central processing unit (CPU) time limit of 20 s at event 2,844,238, simulation time still at t=1.00001402 s simulation time limit of 3 s
packets received by hostB / hostA 0 / 0 4 / 4

With explicit addresses in different prefixes on the two tunnel interfaces, master stops at initialization: Explicit address 2001:db8:b::1 on Ipv6TunnelConfiguratorTestNetwork.borderB.tun0 is not within the link prefix 2001:db8:a::/64. A configuration that put both tunnel interfaces into one prefix to get past that error still initializes and delivers its traffic on this branch, so no migration is needed.

Architectural surface

One NED (Network Description) parameter added to Ipv6TunnelInterface: bool isWireless = default(false), the same declaration as in TunInterface and ExtInterface. NetworkInterface::isWireless() now returns false, and isWired() true, for a tunnel interface. The readers of the two:

  • L3NetworkConfiguratorBase and its three users Ipv6NetworkConfigurator, Ipv4NetworkConfigurator and NextHopNetworkConfigurator: the change this pull request makes. All three run extractTopology(), so the IPv4 and next-hop configurators keep tunnel interfaces apart too.
  • NetworkInterface::computeCarrier(): false for a wired interface without channels, but the lifecycle start of a tunnel interface sets the carrier with setCarrier(true), as before. The interface reports UP CARRIER in the test.
  • Dsdv (Destination-Sequenced Distance Vector routing): an IPv4 routing protocol, which does not run over an IPv6 tunnel.
  • Stp and Rstp (Spanning Tree Protocol and Rapid Spanning Tree Protocol, through isWired()): they serve the ports of an Ethernet bridge, and Stp also requires a multicast interface.
  • VirtualTunnel copies the flag of the real interface it is configured on; none of the shipped configurations put it on an Ipv6TunnelInterface.

No packet format, C++ interface or feature descriptor changes.

Verification

Release build (make MODE=release):

cd tests/module && inet_run_module_tests -m release --no-build -l ERROR -f IPv6_tunnel

The existing IPv6_tunnel, which has one tunnel interface, passes on both.

Full suites, release, on master 93210f4 and on this branch:

cd tests/fingerprint && ./fingerprinttest -s -F tyf -t 6
cd tests/module && inet_run_module_tests -m release --no-build -l ERROR
cd tests/protocol/ipv6 && inet_run_protocol_tests -m release
cd tests/protocol/nd && inet_run_protocol_tests -m release
  • Fingerprints: 1774 rows, 2 failures and 62 errors on both, with the same actual values. The failures are examples/ipv6/nclients ETH and PPP in mipv6-refactoring.csv; the errors are rows whose optional features are disabled in this build. No fingerprint moves: no shipped example, showcase, tutorial or fingerprint configuration names Ipv6TunnelInterface, and the tunnels that Mobile IPv6 (MIPv6) and Proxy Mobile IPv6 (PMIPv6) create appear only after the configurator has run.
  • Module tests: master runs 349 tests, 303 pass; this branch runs 350, 304 pass, the new one included. The same 46 fail on both (34 tcp_*, ConvolutionalCoder12/34, EtherHost_lifecycle, ExternalProcess_3, Ieee80211BitDomain/SymbolDomain, Ieee8021d-Rstp/Stp, IPv6_packet_too_big, MIPv6_tcp_handover, PacketGate_1, UDPSocket_1).
  • Protocol tests: tests/protocol/ipv6 26 of 27 pass on both (Rfc8200OverlappingFragments fails on both); tests/protocol/nd 22 of 37 pass on both, with the same 15 failures.
  • Focused tests in a debug build (make MODE=debug, inet_run_module_tests -m debug --no-build -l ERROR -f IPv6_tunnel): all pass on this branch, and the new test fails on master in debug too.
  • doc/project/enforcement/check-commits.sh, check-classification.sh and check-architecture.sh on src/inet/networklayer/ipv6tunneling and src/inet/networklayer/ipv6: PASS. Statistical tests and check-cpp.sh were not run.

Landing order

git merge-tree against the heads of the open pull requests #1228, #1232, #1252, #1256 and #1264 conflicts only in WHATSNEW, where each adds an item with the same number. The pull request that lands later renumbers its item.


Devin Review

RFC (Request for Comments) 2473 (Generic Packet Tunneling in IPv6)
Section 3 models a tunnel as a point-to-point virtual link between its
entry point and its exit point. Ipv6NetworkConfigurator instead linked
every two Ipv6TunnelInterface modules of a network as members of one
wireless local area network (LAN), and computed routes over those
links. With two tunnels, a border router could route its own tunnel
packets back into the tunnel, and simulation time stopped advancing.
Ipv6TunnelInterface now declares isWireless = default(false), as
TunInterface, the other ITunnelInterface module, does.

NetworkInterface::initialize() classifies an interface as wireless when
it has neither a phys$i nor a phys$o gate, unless the module declares an
isWireless parameter (NetworkInterface.cc:121-124). Ipv6TunnelInterface
has no phys gates and declared no isWireless. The configurator's
extractTopology() links every pair of wireless interfaces that share a
wireless identifier, and getWirelessId() returns "default" for an
interface without a radio that no <wireless> element names
(L3NetworkConfiguratorBase.cc:166-184, 497). That grouping is right for
wireless interfaces; the tunnel interface was the one misclassified.
Ipv4NetworkConfigurator and NextHopNetworkConfigurator run the same
extractTopology(), so they now keep tunnel interfaces apart too.

tests/module/IPv6_tunnel_configurator_routes.test reproduces it with two
border routers and one tunnel each way. Before this change, borderB got the route
2001:db8:2::/64 via fe80:: dev tun0 ahead of the route via eth0. The
tunnel exit point 2001:db8:2::1 is in that prefix, so borderB routed each
tunnel packet into the tunnel again. Simulation time stayed at
t=1.00001402 s until the test's 20 s central processing unit (CPU) time
limit, and hostA and hostB each received 0 of 4 packets; now each
receives 4 of 4. With explicit addresses in different prefixes on the
two tunnel interfaces, the configurator stopped at initialization instead:
"Explicit address 2001:db8:b::1 on
Ipv6TunnelConfiguratorTestNetwork.borderB.tun0 is not within the link
prefix 2001:db8:a::/64".

Change: src.networklayer.ipv6tunneling | behavior.change.fix | test whatsnew

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Devin Review: 1 flag

Not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)

Devin Review

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ipv6tunneling: Ipv6TunnelInterface counts as wireless, so the configurator links all tunnel interfaces and can route a tunnel into itself

1 participant