diff options
author | Alin Serdean <aserdean@cloudbasesolutions.com> | 2017-01-26 23:45:16 +0000 |
---|---|---|
committer | Gurucharan Shetty <guru@ovn.org> | 2017-01-27 13:53:08 -0800 |
commit | 1a2bea5d586e281ab8b821b9ed711afec80dc3bc (patch) | |
tree | 417ee821bcdf114ad5e9330a4f7a105a3b366c4e /datapath-windows | |
parent | e5c6c7f5082dfe6a55e04da85afd206b545d41f5 (diff) | |
download | openvswitch-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')
-rw-r--r-- | datapath-windows/ovsext/Actions.c | 100 |
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) { |