summaryrefslogtreecommitdiff
path: root/datapath-windows/ovsext/PacketIO.c
diff options
context:
space:
mode:
authorSorin Vinturis <svinturis@cloudbasesolutions.com>2015-05-28 21:00:39 +0000
committerBen Pfaff <blp@nicira.com>2015-05-28 14:05:08 -0700
commit58b11928efb7de6fc8356e05dcf17fe9851bb90f (patch)
tree7b401ccff742f3f5fad8549f7e69e38026fc5c12 /datapath-windows/ovsext/PacketIO.c
parent96775a1c0c646e8b860ccfbd63ff6d71e355c6b0 (diff)
downloadopenvswitch-58b11928efb7de6fc8356e05dcf17fe9851bb90f.tar.gz
datapath-windows: Multiple NBLs support for ingress data path
Added support for creating and handling multiple NBLs with only one NB for ingress data path. Signed-off-by: Sorin Vinturis <svinturis at cloudbasesolutions.com> Reported-by: Alessandro Pilotti <apilotti at cloudbasesolutions.com> Reported-at: https://github.com/openvswitch/ovs-issues/issues/2 Acked-by: Nithin Raju <nithin@vmware.com> Signed-off-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'datapath-windows/ovsext/PacketIO.c')
-rw-r--r--datapath-windows/ovsext/PacketIO.c90
1 files changed, 70 insertions, 20 deletions
diff --git a/datapath-windows/ovsext/PacketIO.c b/datapath-windows/ovsext/PacketIO.c
index ed629fdde..6847f5f97 100644
--- a/datapath-windows/ovsext/PacketIO.c
+++ b/datapath-windows/ovsext/PacketIO.c
@@ -44,6 +44,10 @@ extern NDIS_STRING ovsExtFriendlyNameUC;
static VOID OvsFinalizeCompletionList(OvsCompletionList *completionList);
static VOID OvsCompleteNBLIngress(POVS_SWITCH_CONTEXT switchContext,
PNET_BUFFER_LIST netBufferLists, ULONG sendCompleteFlags);
+static NTSTATUS OvsCreateNewNBLsFromMultipleNBs(
+ POVS_SWITCH_CONTEXT switchContext,
+ PNET_BUFFER_LIST *curNbl,
+ PNET_BUFFER_LIST *nextNbl);
__inline VOID
OvsInitCompletionList(OvsCompletionList *completionList,
@@ -237,6 +241,7 @@ OvsStartNBLIngress(POVS_SWITCH_CONTEXT switchContext,
OvsFlowKey key;
UINT64 hash;
PNET_BUFFER curNb;
+ POVS_BUFFER_CONTEXT ctx;
nextNbl = curNbl->Next;
curNbl->Next = NULL;
@@ -258,18 +263,36 @@ OvsStartNBLIngress(POVS_SWITCH_CONTEXT switchContext,
}
#endif /* NDIS_SUPPORT_NDIS640 */
- /* Ethernet Header is a guaranteed safe access. */
- curNb = NET_BUFFER_LIST_FIRST_NB(curNbl);
- if (curNb->Next != NULL) {
- /* XXX: This case is not handled yet. */
+ ctx = OvsInitExternalNBLContext(switchContext, curNbl,
+ sourcePort == switchContext->virtualExternalPortId);
+ if (ctx == NULL) {
RtlInitUnicodeString(&filterReason,
- L"Dropping NBLs with multiple NBs");
+ L"Cannot allocate external NBL context.");
+
OvsStartNBLIngressError(switchContext, curNbl,
sendCompleteFlags, &filterReason,
NDIS_STATUS_RESOURCES);
continue;
- } else {
- POVS_BUFFER_CONTEXT ctx;
+ }
+
+ /* Ethernet Header is a guaranteed safe access. */
+ curNb = NET_BUFFER_LIST_FIRST_NB(curNbl);
+ if (curNb->Next != NULL) {
+ /* Create a NET_BUFFER_LIST for each NET_BUFFER. */
+ status = OvsCreateNewNBLsFromMultipleNBs(switchContext,
+ &curNbl,
+ &nextNbl);
+ if (!NT_SUCCESS(status)) {
+ RtlInitUnicodeString(&filterReason,
+ L"Cannot allocate NBLs with single NB.");
+
+ OvsStartNBLIngressError(switchContext, curNbl,
+ sendCompleteFlags, &filterReason,
+ NDIS_STATUS_RESOURCES);
+ continue;
+ }
+ }
+ {
OvsFlow *flow;
/* Take the DispatchLock so none of the VPORTs disconnect while
@@ -280,19 +303,6 @@ OvsStartNBLIngress(POVS_SWITCH_CONTEXT switchContext,
NdisAcquireRWLockRead(switchContext->dispatchLock, &lockState,
dispatch);
- ctx = OvsInitExternalNBLContext(switchContext, curNbl,
- sourcePort == switchContext->virtualExternalPortId);
- if (ctx == NULL) {
- RtlInitUnicodeString(&filterReason,
- L"Cannot allocate external NBL context.");
-
- OvsStartNBLIngressError(switchContext, curNbl,
- sendCompleteFlags, &filterReason,
- NDIS_STATUS_RESOURCES);
- NdisReleaseRWLock(switchContext->dispatchLock, &lockState);
- continue;
- }
-
vport = OvsFindVportByPortIdAndNicIndex(switchContext, sourcePort,
sourceIndex);
if (vport == NULL || vport->ovsState != OVS_STATE_CONNECTED) {
@@ -485,3 +495,43 @@ OvsExtCancelSendNBL(NDIS_HANDLE filterModuleContext,
/* All send requests get completed synchronously, so there is no need to
* implement this callback. */
}
+
+static NTSTATUS
+OvsCreateNewNBLsFromMultipleNBs(POVS_SWITCH_CONTEXT switchContext,
+ PNET_BUFFER_LIST *curNbl,
+ PNET_BUFFER_LIST *nextNbl)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ PNET_BUFFER_LIST newNbls = NULL;
+ PNET_BUFFER_LIST lastNbl = NULL;
+ PNET_BUFFER_LIST nbl = NULL;
+ POVS_BUFFER_CONTEXT bufContext = NULL;
+ BOOLEAN error = TRUE;
+
+ do {
+ /* Create new NBLs from curNbl with multiple net buffers. */
+ newNbls = OvsPartialCopyToMultipleNBLs(switchContext,
+ *curNbl, 0, 0, TRUE);
+ if (NULL == newNbls) {
+ OVS_LOG_ERROR("Failed to allocate NBLs with single NB.");
+ status = NDIS_STATUS_RESOURCES;
+ break;
+ }
+
+ nbl = newNbls;
+ while (nbl) {
+ lastNbl = nbl;
+ nbl = NET_BUFFER_LIST_NEXT_NBL(nbl);
+ }
+ lastNbl->Next = *nextNbl;
+ *nextNbl = newNbls->Next;
+ *curNbl = newNbls;
+ (*curNbl)->Next = NULL;
+
+ OvsCompleteNBL(switchContext, *curNbl, TRUE);
+
+ error = FALSE;
+ } while (error);
+
+ return status;
+}