summaryrefslogtreecommitdiff
path: root/datapath-windows/ovsext/Actions.c
diff options
context:
space:
mode:
authorAlin Serdean <aserdean@cloudbasesolutions.com>2017-01-26 23:45:16 +0000
committerGurucharan Shetty <guru@ovn.org>2017-01-27 13:53:08 -0800
commit1a2bea5d586e281ab8b821b9ed711afec80dc3bc (patch)
tree417ee821bcdf114ad5e9330a4f7a105a3b366c4e /datapath-windows/ovsext/Actions.c
parente5c6c7f5082dfe6a55e04da85afd206b545d41f5 (diff)
downloadopenvswitch-1a2bea5d586e281ab8b821b9ed711afec80dc3bc.tar.gz
datapath-windows: Add function to get continuous buffer from context
This patch extracts the code that tries to get a continuous IPv4 header buffer from the function 'OvsUpdateIPv4Header' and moves it to a new function 'OvsGetHeaderBySize'. The new function can be used later when trying to change the UDP/TCP/MPLS etc., headers. Signed-off-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com> Acked-by: Sairam Venugopal <vsairam@vmware.com> Signed-off-by: Gurucharan Shetty <guru@ovn.org>
Diffstat (limited to 'datapath-windows/ovsext/Actions.c')
-rw-r--r--datapath-windows/ovsext/Actions.c100
1 files changed, 62 insertions, 38 deletions
diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c
index 760888e32..467bfbc82 100644
--- a/datapath-windows/ovsext/Actions.c
+++ b/datapath-windows/ovsext/Actions.c
@@ -1306,64 +1306,51 @@ OvsUpdateEthHeader(OvsForwardingContext *ovsFwdCtx,
return NDIS_STATUS_SUCCESS;
}
+
/*
*----------------------------------------------------------------------------
- * OvsUpdateIPv4Header --
- * Updates the IPv4 header in ovsFwdCtx.curNbl inline based on the
- * specified key.
+ * OvsGetHeaderBySize --
+ * Tries to retrieve a continuous buffer from 'ovsFwdCtx->curnbl' of size
+ * 'size'.
+ * If the original buffer is insufficient it will, try to clone the net
+ * buffer list and force the size.
+ * Returns 'NULL' on failure or a pointer to the first byte of the data
+ * in the first net buffer of the net buffer list 'nbl'.
*----------------------------------------------------------------------------
*/
-static __inline NDIS_STATUS
-OvsUpdateIPv4Header(OvsForwardingContext *ovsFwdCtx,
- const struct ovs_key_ipv4 *ipAttr)
+PUINT8 OvsGetHeaderBySize(OvsForwardingContext *ovsFwdCtx,
+ UINT32 size)
{
PNET_BUFFER curNb;
+ UINT32 mdlLen, packetLen;
PMDL curMdl;
ULONG curMdlOffset;
- PUINT8 bufferStart;
- UINT32 mdlLen, hdrSize, packetLen;
- OVS_PACKET_HDR_INFO *layers = &ovsFwdCtx->layers;
- NDIS_STATUS status;
- IPHdr *ipHdr;
- TCPHdr *tcpHdr = NULL;
- UDPHdr *udpHdr = NULL;
-
- ASSERT(layers->value != 0);
+ PUINT8 start;
- /*
- * Peek into the MDL to get a handle to the IP header and if required
- * the TCP/UDP header as well. We check if the required headers are in one
- * contiguous MDL, and if not, we copy them over to one MDL.
- */
curNb = NET_BUFFER_LIST_FIRST_NB(ovsFwdCtx->curNbl);
ASSERT(curNb->Next == NULL);
packetLen = NET_BUFFER_DATA_LENGTH(curNb);
curMdl = NET_BUFFER_CURRENT_MDL(curNb);
- NdisQueryMdl(curMdl, &bufferStart, &mdlLen, LowPagePriority);
- if (!bufferStart) {
+ NdisQueryMdl(curMdl, &start, &mdlLen, LowPagePriority);
+ if (!start) {
ovsActionStats.noResource++;
- return NDIS_STATUS_RESOURCES;
+ return NULL;
}
+
curMdlOffset = NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
mdlLen -= curMdlOffset;
ASSERT((INT)mdlLen >= 0);
- if (layers->isTcp || layers->isUdp) {
- hdrSize = layers->l4Offset +
- layers->isTcp ? sizeof (*tcpHdr) : sizeof (*udpHdr);
- } else {
- hdrSize = layers->l3Offset + sizeof (*ipHdr);
- }
-
/* Count of number of bytes of valid data there are in the first MDL. */
mdlLen = MIN(packetLen, mdlLen);
- if (mdlLen < hdrSize) {
+ if (mdlLen < size) {
PNET_BUFFER_LIST newNbl;
+ NDIS_STATUS status;
newNbl = OvsPartialCopyNBL(ovsFwdCtx->switchContext, ovsFwdCtx->curNbl,
- hdrSize, 0, TRUE /*copy NBL info*/);
+ size, 0, TRUE /*copy NBL info*/);
if (!newNbl) {
ovsActionStats.noCopiedNbl++;
- return NDIS_STATUS_RESOURCES;
+ return NULL;
}
OvsCompleteNBLForwardingCtx(ovsFwdCtx,
L"Complete after partial copy.");
@@ -1372,25 +1359,62 @@ OvsUpdateIPv4Header(OvsForwardingContext *ovsFwdCtx,
newNbl, ovsFwdCtx->srcVportNo, 0,
NET_BUFFER_LIST_SWITCH_FORWARDING_DETAIL(newNbl),
NULL, &ovsFwdCtx->layers, FALSE);
+
if (status != NDIS_STATUS_SUCCESS) {
OvsCompleteNBLForwardingCtx(ovsFwdCtx,
L"OVS-Dropped due to resources");
- return NDIS_STATUS_RESOURCES;
+ return NULL;
}
curNb = NET_BUFFER_LIST_FIRST_NB(ovsFwdCtx->curNbl);
ASSERT(curNb->Next == NULL);
curMdl = NET_BUFFER_CURRENT_MDL(curNb);
- NdisQueryMdl(curMdl, &bufferStart, &mdlLen, LowPagePriority);
+ NdisQueryMdl(curMdl, &start, &mdlLen, LowPagePriority);
if (!curMdl) {
ovsActionStats.noResource++;
- return NDIS_STATUS_RESOURCES;
+ return NULL;
}
curMdlOffset = NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
mdlLen -= curMdlOffset;
- ASSERT(mdlLen >= hdrSize);
+ ASSERT(mdlLen >= size);
}
- bufferStart += curMdlOffset;
+
+ return start + curMdlOffset;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ * OvsUpdateIPv4Header --
+ * Updates the IPv4 header in ovsFwdCtx.curNbl inline based on the
+ * specified key.
+ *----------------------------------------------------------------------------
+ */
+static __inline NDIS_STATUS
+OvsUpdateIPv4Header(OvsForwardingContext *ovsFwdCtx,
+ const struct ovs_key_ipv4 *ipAttr)
+{
+ PUINT8 bufferStart;
+ UINT32 hdrSize;
+ OVS_PACKET_HDR_INFO *layers = &ovsFwdCtx->layers;
+ IPHdr *ipHdr;
+ TCPHdr *tcpHdr = NULL;
+ UDPHdr *udpHdr = NULL;
+
+ ASSERT(layers->value != 0);
+
+ if (layers->isTcp || layers->isUdp) {
+ hdrSize = layers->l4Offset +
+ layers->isTcp ? sizeof (*tcpHdr) : sizeof (*udpHdr);
+ } else {
+ hdrSize = layers->l3Offset + sizeof (*ipHdr);
+ }
+
+ bufferStart = OvsGetHeaderBySize(ovsFwdCtx, hdrSize);
+ if (!bufferStart) {
+ return NDIS_STATUS_RESOURCES;
+ }
+
ipHdr = (IPHdr *)(bufferStart + layers->l3Offset);
if (layers->isTcp) {