Dual-stack socket and FWPM_LAYER_ALE_ENDPOINT_CLOSURE_V4

Hello,

I have an issue with handling dual-stack sockets in my driver with WFP callouts.

The driver performs out-of-band inspection:

  • clones a network packet
  • sends the cloned packet to a worker thread
  • drops the original packet

For now the worker thread just injects cloned packets back to the stream.

The test application sends WOL packets by using UDP:

  • creates a socket
  • configures it to be used as dual-stack socket (by using setsockopt and clearing IPV6_V6ONLY flag)
  • sends a small datagram to a nother PC
  • closes the socket

When the test application uses only IPv4 (192.168.56.25), the following callouts are executed in the driver:

  • FWPM_LAYER_ALE_RESOURCE_ASSIGNMENT_V4
  • FWPM_LAYER_ALE_AUTH_CONNECT_V4
  • FWPM_LAYER_ALE_FLOW_ESTABLISHED_V4
  • FWPM_LAYER_DATAGRAM_DATA_V4
  • FWPM_LAYER_DATAGRAM_DATA_V4 (when the data is injected to the stream from the worker thread)
  • FWPM_LAYER_OUTBOUND_TRANSPORT_V4
  • FWPM_LAYER_ALE_ENDPOINT_CLOSURE_V4
  • FWPM_LAYER_ALE_RESOURCE_RELEASE_V4

In this case the another PC receives a network packet (I’m using Wireshark to check that).

When the test application configures a dual-stack socket and uses IPv6 (::FFFF:ACA8:3819, the same test PC), the second FWPM_LAYER_DATAGRAM_DATA_V4 isn’t called. The FwpsInjectTransportSendAsync0 returns SUCCESS, the completion routine is executed, but NET_BUFFER_LIST status is SUCCESS too. Also FWPM_LAYER_ALE_ENDPOINT_CLOSURE_V4 is not called (in this callout I postpone closing the socket by using FwpsPendClassify0). As a result, a network packet is not delivered to another PC.

I’m not interested in handling IPv6 in my driver, so there are no IPv6 callouts registered. Also I haven’t seen this issue with TCP or when I modified the application to sleep some time before closing the socket.

Does anyone know why FWPM_LAYER_ALE_ENDPOINT_CLOSURE_V4 is not called in this case? Or there are some special rules to handle dual-sockets in WFP driver?

For Dual stack sockets you’ll need to also register at the V6 layers. You can filter “true” IPV6 traffic out by using INETADDR_ISV4MAPPED

Hello @Jason_Stephenson ,

Thanks a lot. Adding callouts for IPv6 fixed the issue. Actually I added only RELEASE and CLOSURE callouts and it’s working.