UDP-ESP SAs and Parser Entries (NDIS 5.1)
Note NDIS 5. x has been deprecated and is superseded by NDIS 6. x. For new NDIS driver development, see Network Drivers Starting with Windows Vista. For information about porting NDIS 5. x drivers to NDIS 6. x, see Porting NDIS 5.x Drivers to NDIS 6.0.A miniport driver that supports UDP-ESP encapsulation must maintain a list of parser entries. A parser entry contains information that the miniport driver's NIC requires to parse incoming UDP-ESP packets on one or more offloaded security associations (SAs).
A parser entry contains the following information:
The UDP-ESP encapsulation type.
Currently, only one encapsulation type is supported. For a description of the basic UDP-ESP encapsulation types, see UDP-ESP Encapsulation Types.
The destination encapsulation port.
The NIC should look for the destination port in the UDP header of inbound UDP-encapsulated packets that it processes on the offloaded SAs. Currently, UDP encapsulation of ESP packets is supported only on port 4500.
The TCP/IP transport maintains its own list of parser entries that it has offloaded to the miniport driver. When adding or deleting a UDP-ESP SA, the transport and miniport driver use a handle to identify a particular parser entry.
Note that parser entries allow UDP-ESP functionality to be extended, if necessary, to accommodate different encapsulation types and more than one port for each encapsulation type.
The TCP/IP transport requests a miniport driver to add one or more UDP-ESP SAs, and the parser entry for these SAs, by issuing an OID_TCP_TASK_IPSEC_ADD_UDPESP_SArequest. The EncapTypeEntrymember of the OFFLOAD_IPSEC_ADD_UDPESP_SA structure contains the parser entry information.
Before issuing an OID_TCP_TASK_IPSEC_ADD_UDPESP_SA request, the TCP/IP transport determines whether the parser entry for the SAs that is being offloaded is in its parser entry list for the specified IP interface.
If the parser entry is not in the transport's list, the transport creates its own copy of the entry and sets the EncapTypeEntryOffloadHandle member of the OFFLOAD_IPSEC_ADD_UDPESP_SA structure to NULL. The transport then issues the OID_TCP_TASK_IPSEC_ADD_UDPESP_SA request. After receiving the request, the miniport driver determines whether the parser entry that the EncapTypeEntry specified is in the NIC's parser entry list.
- If the specified parser entry is not in the NIC's parser entry list, the miniport driver creates the parser entry by using the encapsulation type and destination port specified in EncapTypeEntry and adds the parser entry to the NIC's parser entry list. The miniport driver then offloads the SAs specified in the OID_TCP_TASK_IPSEC_ADD_UDPESP_SA request. After successfully completing the OID request, the miniport driver returns a handle in EncapTypeEntryOffloadHandle that identifies the newly created parser entry. The miniport driver also returns a handle that identifies the offloaded SAs in the OffloadHandle member of the OFFLOAD_IPSEC_ADD_UDPESP_SA structure.
- If the specified parser entry is already in the NIC's parser entry list, the miniport driver simply returns the handle in EncapTypeEntryOffloadHandle for the existing parser entry. The miniport driver also returns a handle that identifies the offloaded SAs in the OffloadHandle member of the OFFLOAD_IPSEC_ADD_UDPESP_SA structure.
If the miniport driver completes the OID_TCP_TASK_IPSEC_ADD_UDPESP_SA request successfully, the transport adds its copy of the new parser entry to its own parser entry list for the given IP interface. In addition, the transport increments the reference count for the parser entry by one. The transport uses this reference count to enumerate how many offloaded UDP-ESP SAs are associated with the parser entry.
If the miniport driver fails the OID_TCP_TASK_IPSEC_ADD_UDPESP_SA request, the transport discards its copy of the parser entry. If the miniport driver fails such a request, it must ensure that it has not, in fact, added the parser entry and offloaded the SAs.
If the parser entry is already in the transport's parser entry list, the miniport driver has already added the parser entry in response to a previous OID_TCP_TASK_IPSEC_ADD_UDPESP_SA request. In this case, the transport increments the reference count for the parser entry by one and sets the EncapTypeEntryOffloadHandle to the value that the miniport driver previously returned. The transport then issues an OID_TCP_TASK_IPSEC_ADD_UDPESP_SA request This requests the miniport driver to use an existing parser entry for the additional SAs that are being offloaded. In this case, the miniport driver should simply return an OffloadHandle that identifies the offloaded SAs. If the OID_TCP_TASK_IPSEC_ADD_UDPESP_SA request fails, the transport decrements the reference count for the parser entry.
The TCP/IP transport requests a miniport driver to delete one or more SAs and possibly the parser entry for these SAs by issuing an OID_TCP_TASK_IPSEC_DELETE_UDPESP_SArequest.
Before issuing this request, the TCP/IP transport decrements the reference count for the parser entry that is associated with the SAs to be deleted. The transport then tests whether the reference count is zero.
If the reference count is not zero, the parser entry is associated with one or more other SAs that are currently offloaded to the NIC. In this case, the transport sets the EncapTypeEntryOffldHandle member of the OFFLOAD_IPSEC_DELETE_UDPESP_SA structure to NULL. After it receives the OID_TCP_TASK_IPSEC_DELETE_UDPESP_SA request, the miniport driver simply deletes the SAs that are specified in the OID_TCP_TASK_IPSEC_DELETE_UDPESP_SA request.
If the reference count is zero, the parser entry is not associated with any other SAs that have been offloaded to the NIC. In this case, the transport sets the EncapTypeEntryOffldHandle member to the value of the parser entry handle that the miniport driver previously returned. The miniport driver deletes both the specified parser entry and the specified SAs.
If the miniport driver fails the OID_TCP_TASK_IPSEC_DELETE_UDPESP_SA request, it should mark the specified SAs and, if appropriate, the specified parser entry for deletion and perform the deletion later. To process incoming packets, the miniport driver must not use a parser entry or SA that is marked for deletion.
Note that a transport could request a miniport driver to delete an SA and/or a parser entry before the miniport driver completes adding that SA and/or parser entry. The miniport driver must therefore serialize the deletion operation with the addition operation.