Route normal, DHCP, and mobile nic creation through one helper that
selects the shared backend when dev_name is configured.
Keep dedicated nic creation as the default for configs without a
dev_name, and keep no_tun handling in the existing callers.
Store a process-wide shared virtual nic registry behind each instance
so networks with the same dev_name attach to the same shared device.
Create the shared virtual nic dispatcher from the mobile tun fd.
Later shared members attach through their ring tunnel and do not
consume another fd. Dedicated mobile nic creation stays unchanged.
Fix mobile no-magic-dns cfg so the mobile tun path checks without
enabling magic-dns.
Route shared nic IP and route configuration through member claims.
Repeated addresses or routes now touch the OS device only when the
first owner appears, and are removed only after the last owner leaves.
Forward NicBackend shared operations to the member claim layer.
Dynamic proxy and public IPv6 route updates now go through NicBackend,
so they use the same ownership merge behavior.
Clean member claims when shared member registration is dropped. Keep
raw ifcfg access for non-Linux platform cleanup only, and document
that this raw path does not carry the netns guard.
Replace full flow table clears with a small FIFO order queue so overflow evicts only older flow ownership hints.
Keep lookup read-only on the packet hot path and prune stale queue entries when a shared member unregisters.
Parse shared virtual nic flow keys directly from IP payload bytes instead of building pnet packet wrappers on the dispatcher hot path.
Use a local HashMap for flow owner lookup and clear the bounded table on overflow instead of removing a BTreeMap entry by key order.
Move shared member and flow ownership state into the dispatcher task.
Use control messages for member register and unregister events.
Keep the member table lock off the packet forwarding path.
Add the shared NIC dispatcher that owns the underlying VirtualNic tunnel.
Connect member ring tunnels through a private member table.
Track reverse flow ownership from packets written by a member.
Replies read from the shared device go back to the same member.
Packets without an owner fall back to any active member.
Mark the shared NIC invalid when the underlying tunnel closes or fails.
Notify members so their NicCtx can rebuild.
Use create_ring_tunnel_pair for member-level shared NIC tunnels.
That replaces the custom packet stream and sink implementation.
Keep one side of each ring tunnel in SharedVirtualNic's member map.
Later dispatcher code can connect those endpoints to the shared device.
Add a shared NicCtx constructor that obtains a SharedVirtualNicMember from the registry and wraps it in NicBackend::Shared.
Keep NicCtx::new on the dedicated backend path so existing runtime behavior does not change before the shared tunnel implementation is ready.
Replace NicCtx's direct VirtualNic field with NicBackend while keeping the constructor on the dedicated backend path.
Move existing device creation, ifcfg lookup, IP assignment, and public IPv6 updater calls through backend helpers so shared mode can be wired in a later commit without changing the dedicated flow.
Introduce SharedVirtualNicMember as the per-instance handle for a shared virtual NIC and add a registry helper to create members.
Add NicBackend so NicCtx can later choose between dedicated VirtualNic and shared member-backed tunnel creation without changing the existing dedicated path.
Add a small registry keyed by dev_name so shared-mode setup can reuse one SharedVirtualNic per device name.
Track invalid shared NICs through a shared flag and replace them on the next get_or_create call.
Move TUN-specific configuration into VirtualNicConfig so VirtualNic and SharedVirtualNic no longer depend on ArcGlobalCtx.
Keep global context side effects in NicCtx, including the Windows generated device-name writeback.
introduce my peer route id and peer id is duplicated only when peer
route id is not same.
this problem occurs because update_self may increase my peer info
version and propagate to ther nodes.
if smoltcp bind only once on tcp socket, it can only accept exactly
one syn packet in one round. other syn packets will be dropped and
client will receive a RST packet.