When using packet forwarding on Windows computer, adjacent NBLs may
represent packet fragments. Those NBLs must not be completed separately,
but in a single NdisMSendNetBufferListsComplete() call.
This fixes a bugcheck on Windows Server with RRAS role and IP forwarding
packets to Wintun adapter.
Signed-off-by: Simon Rozman <simon@rozman.si>
Before duplicating a handle elsewhere and closing the original process
would result in disaster. Also, it turns out that TunHaltEx can be
called before the handles are all closed, so we need to unregister prior
to freeing the ctx, lest disaster occurs. Finally, now that we have a
few different things happening with registration and deregistration, we
serialize all accesses with an eresource, a bit heavy-weight but
sufficient.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
We mark all atomic variables as volatile and have our atomic accessors
built around that. We probably, therefore, want Linux-style
READ/WRITE_ONCE semantics of implying memory barriers. /volatile:ms does
this automatically.
This was already the default on amd64 and x86 but not on ARM.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Reported-by: Lev Stipakov <lstipakov@gmail.com>
Previously we had to spin for a minimum of 15ms because the tick
interval is 156250 on NT. On linux, usually trips to the high
performance timers are discouraged because if they don't hit the RDTSC
path (due to being unstable or the like), they hit more expensive
hardware. I assume that's probably the same on NT, but all of tcpip.sys
and ndis.sys uses the performance counters too, so what are we going to
do?
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
The Empty event state is now set according to
Ctx->Device.Receive.ActiveNbls.Head != NULL. But, we still have to clear
the Empty event inside the TransitionLock to prevent race with
TunPause().
Signed-off-by: Simon Rozman <simon@rozman.si>
Should NBL allocation persist to fail, the receive ring could eventually
fill up as there will be no TunReturnNetBufferLists() calls to advance
its head.
Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is in many ways wrong, but when we're dealing with whql
imports, there's often a large gap in time, and it's useful to be able
to just restore everything exactly how it was prior and then build only
installer.dll and the msm.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
NdisMGetDeviceProperty() should always return non-NULL
FunctionalDeviceObject according to _Outptr_opt_. An explicit
FunctionalDeviceObject NULL check has been added to keep the SDV happy
and not calling our driver "defective".
Signed-off-by: Simon Rozman <simon@rozman.si>
By attaching to NDIS device instead of creating our own device for I/O,
the adapter is always running before client is able to connect and
register rings. NDIS also won't allow adapter to pause with connected
clients.
Signed-off-by: Simon Rozman <simon@rozman.si>
With no PnP notifications and custom surprise removal code we do not
need the TUN_FLAGS_PRESENT any more. The traffic is stopped when handle
is closed or adapter is somehow paused. Though by reusing the NDIS device
for our I/O, the adapter will not be able to pause with a client
connected.
Signed-off-by: Simon Rozman <simon@rozman.si>
Before the TunProcessReceiveData() thread terminates or adapter is
paused, we wait for all receive NBLs to be returned. Unfortunately,
IoReleaseRemoveLockAndWait() leaves the remove lock in non reusable
state.
To be able to start receiving packets on existing adapter again, we
(re)initialize the remove lock on ring registration or adapter resume.
The former addresses TunProcessReceiveData()'s
IoReleaseRemoveLockAndWait() call, the later addresses the TunPause()'s.
Signed-off-by: Simon Rozman <simon@rozman.si>
This commit moves NBL post-processing (moving ring head, releasing NBL)
to MINIPORT_RETURN_NET_BUFFER_LISTS handler.
Signed-off-by: Simon Rozman <simon@rozman.si>
We do not need to share-lock the TransitionLock for complete NBL chain.
This commit should improve better state transition response, thou until
NDIS is sending a single NBL per MINIPORT_SEND_NET_BUFFER_LISTS call,
this should not have a considerable effect.
Since the skibNbl: call of NdisMSendNetBufferListsComplete() is made
inside the TransactionLock at dispatch IRQL, a dispatch IRQL hint was
added to the NdisMSendNetBufferListsComplete() call.
Signed-off-by: Simon Rozman <simon@rozman.si>