Skip to content

Commit

Permalink
datapath-windows: Upcall NL packet format: Call NL missed packet func…
Browse files Browse the repository at this point in the history
…tion

Remove hard coded queue is, pass the key rather the tunnel key,
Remove the none NL implementation

Signed-off-by: Eitan Eliahu <[email protected]>
Acked-by: Ankur Sharma <[email protected]>
Acked-by: Nithin Raju <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
EitanEliahu authored and blp committed Oct 15, 2014
1 parent 1293a62 commit 640ebde
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 282 deletions.
29 changes: 12 additions & 17 deletions datapath-windows/ovsext/Actions.c
Original file line number Diff line number Diff line change
Expand Up @@ -558,14 +558,11 @@ OvsDoFlowLookupOutput(OvsForwardingContext *ovsFwdCtx)
UINT32 num = 0;
ovsFwdCtx->switchContext->datapath.misses++;
InitializeListHead(&missedPackets);
status = OvsCreateAndAddPackets(
OVS_DEFAULT_PACKET_QUEUE, NULL, 0, OVS_PACKET_CMD_MISS,
ovsFwdCtx->srcVportNo,
key.tunKey.dst != 0 ?
(OvsIPv4TunnelKey *)&key.tunKey : NULL,
ovsFwdCtx->curNbl,
ovsFwdCtx->tunnelRxNic != NULL, &ovsFwdCtx->layers,
ovsFwdCtx->switchContext, &missedPackets, &num);
status = OvsCreateAndAddPackets(NULL, 0, OVS_PACKET_CMD_MISS,
ovsFwdCtx->srcVportNo,
&key,ovsFwdCtx->curNbl,
ovsFwdCtx->tunnelRxNic != NULL, &ovsFwdCtx->layers,
ovsFwdCtx->switchContext, &missedPackets, &num);
if (num) {
OvsQueuePackets(OVS_DEFAULT_PACKET_QUEUE, &missedPackets, num);
}
Expand Down Expand Up @@ -1472,7 +1469,6 @@ OvsActionsExecute(POVS_SWITCH_CONTEXT switchContext,
PNL_ATTR userdataAttr;
PNL_ATTR queueAttr;
POVS_PACKET_QUEUE_ELEM elem;
UINT32 queueId = OVS_DEFAULT_PACKET_QUEUE;
BOOLEAN isRecv = FALSE;

POVS_VPORT_ENTRY vport = OvsFindVportByPortNo(switchContext,
Expand All @@ -1488,14 +1484,13 @@ OvsActionsExecute(POVS_SWITCH_CONTEXT switchContext,
queueAttr = NlAttrFindNested(a, OVS_USERSPACE_ATTR_PID);
userdataAttr = NlAttrFindNested(a, OVS_USERSPACE_ATTR_USERDATA);

elem = OvsCreateQueuePacket(queueId, (PVOID)userdataAttr,
userdataAttr->nlaLen,
OVS_PACKET_CMD_ACTION,
portNo, (OvsIPv4TunnelKey *)&key->tunKey,
ovsFwdCtx.curNbl,
NET_BUFFER_LIST_FIRST_NB(ovsFwdCtx.curNbl),
isRecv,
layers);
elem = OvsCreateQueueNlPacket((PVOID)userdataAttr,
userdataAttr->nlaLen,
OVS_PACKET_CMD_ACTION,
portNo, key,ovsFwdCtx.curNbl,
NET_BUFFER_LIST_FIRST_NB(ovsFwdCtx.curNbl),
isRecv,
layers);
if (elem) {
LIST_ENTRY missedPackets;
InitializeListHead(&missedPackets);
Expand Down
7 changes: 2 additions & 5 deletions datapath-windows/ovsext/PacketIO.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,12 +287,9 @@ OvsStartNBLIngress(POVS_SWITCH_CONTEXT switchContext,
OvsReleaseDatapath(datapath, &dpLockState);

datapath->misses++;
status = OvsCreateAndAddPackets(OVS_DEFAULT_PACKET_QUEUE,
NULL, 0, OVS_PACKET_CMD_MISS,
status = OvsCreateAndAddPackets(NULL, 0, OVS_PACKET_CMD_MISS,
portNo,
key.tunKey.dst != 0 ?
(OvsIPv4TunnelKey *)&key.tunKey :
NULL, curNbl,
&key, curNbl,
sourcePort ==
switchContext->externalPortId,
&layers, switchContext,
Expand Down
4 changes: 2 additions & 2 deletions datapath-windows/ovsext/Tunnel.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,8 @@ OvsInjectPacketThroughActions(PNET_BUFFER_LIST pNbl,
POVS_PACKET_QUEUE_ELEM elem;

datapath->misses++;
elem = OvsCreateQueuePacket(1, NULL, 0, OVS_PACKET_CMD_MISS,
portNo, &key.tunKey, pNbl, curNb,
elem = OvsCreateQueueNlPacket(NULL, 0, OVS_PACKET_CMD_MISS,
portNo, &key, pNbl, curNb,
TRUE, &layers);
if (elem) {
/* Complete the packet since it was copied to user buffer. */
Expand Down
250 changes: 4 additions & 246 deletions datapath-windows/ovsext/User.c
Original file line number Diff line number Diff line change
Expand Up @@ -517,247 +517,6 @@ OvsGetQueue(UINT32 queueId)
return queue->instance != NULL ? queue : NULL;
}

/*
*----------------------------------------------------------------------------
* OvsCreateQueuePacket --
*
* Create a packet which will be forwarded to user space.
*
* InputParameter:
* queueId Identify the queue the packet to be inserted
* This will be used when multiple queues is supported
* in userspace
* userData: when cmd is user action, this field contain
* user action data.
* userDataLen: as name indicated
* cmd: either miss or user action
* inPort: datapath port id from which the packet is received.
* tunnelKey: tunnelKey for tunneled packet
* nbl: the NET_BUFFER_LIST which contain the packet
* nb: the packet
* isRecv: This is used to decide how to interprete the csum info
* hdrInfo: include hdr info initialized during flow extraction.
*
* Results:
* NULL if fail to create the packet
* The packet element otherwise
*----------------------------------------------------------------------------
*/
POVS_PACKET_QUEUE_ELEM
OvsCreateQueuePacket(UINT32 queueId,
PVOID userData,
UINT32 userDataLen,
UINT32 cmd,
UINT32 inPort,
OvsIPv4TunnelKey *tunnelKey,
PNET_BUFFER_LIST nbl,
PNET_BUFFER nb,
BOOLEAN isRecv,
POVS_PACKET_HDR_INFO hdrInfo)
{
#define VLAN_TAG_SIZE 4
UINT32 allocLen, dataLen, extraLen = 0;
POVS_PACKET_QUEUE_ELEM elem;
PMDL mdl;
UINT8 *src, *dst;
NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo;
NDIS_NET_BUFFER_LIST_8021Q_INFO vlanInfo;

if (!OvsGetQueue(queueId)) {
/*
* There is no userspace queue created yet, so there is no point for
* creating a new packet to be queued.
*/
return NULL;
}

csumInfo.Value = NET_BUFFER_LIST_INFO(nbl, TcpIpChecksumNetBufferListInfo);

if (isRecv && (csumInfo.Receive.TcpChecksumFailed ||
(csumInfo.Receive.UdpChecksumFailed &&
!hdrInfo->udpCsumZero) ||
csumInfo.Receive.IpChecksumFailed)) {
OVS_LOG_INFO("Packet dropped due to checksum failure.");
ovsUserStats.dropDuetoChecksum++;
return NULL;
}

vlanInfo.Value = NET_BUFFER_LIST_INFO(nbl, Ieee8021QNetBufferListInfo);
if (vlanInfo.TagHeader.VlanId) {
/*
* We may also need to check priority XXX
*/
extraLen = VLAN_TAG_SIZE;
}

dataLen = NET_BUFFER_DATA_LENGTH(nb);
allocLen = sizeof (OVS_PACKET_QUEUE_ELEM) + userDataLen + dataLen +
extraLen;

elem = (POVS_PACKET_QUEUE_ELEM)OvsAllocateMemory(allocLen);
if (elem == NULL) {
ovsUserStats.dropDuetoResource++;
return NULL;
}
elem->hdrInfo.value = hdrInfo->value;
elem->packet.totalLen = sizeof (OVS_PACKET_INFO) + userDataLen + dataLen +
extraLen;
elem->packet.queue = queueId;
elem->packet.userDataLen = userDataLen;
elem->packet.inPort = inPort;
elem->packet.cmd = cmd;
if (cmd == (UINT32)OVS_PACKET_CMD_MISS) {
ovsUserStats.miss++;
} else {
ovsUserStats.action++;
}
elem->packet.packetLen = dataLen + extraLen;
if (tunnelKey) {
RtlCopyMemory(&elem->packet.tunnelKey, tunnelKey,
sizeof (*tunnelKey));
} else {
RtlZeroMemory(&elem->packet.tunnelKey,
sizeof (elem->packet.tunnelKey));
}

dst = elem->packet.data;
if (userDataLen) {
RtlCopyMemory(dst, userData, userDataLen);
dst = dst + userDataLen;
}
dst += extraLen;

mdl = NET_BUFFER_CURRENT_MDL(nb);
src = NdisGetDataBuffer(nb, dataLen, dst, 1, 0);
if (src == NULL) {
OvsFreeMemory(elem);
ovsUserStats.dropDuetoResource++;
return NULL;
} else if (src != dst) {
/* Copy the data from the NDIS buffer to dst. */
RtlCopyMemory(dst, src, dataLen);
}

dst = elem->packet.data + userDataLen + extraLen;
/*
* Fix IP hdr if necessary
*/
if ((isRecv && csumInfo.Receive.IpChecksumValueInvalid) ||
(!isRecv && csumInfo.Transmit.IsIPv4 &&
csumInfo.Transmit.IpHeaderChecksum)) {
PIPV4_HEADER ipHdr = (PIPV4_HEADER)(dst + hdrInfo->l3Offset);
ASSERT(elem->hdrInfo.isIPv4);
ASSERT(ipHdr->Version == 4);
ipHdr->HeaderChecksum = IPChecksum((UINT8 *)ipHdr,
ipHdr->HeaderLength << 2,
(UINT16)~ipHdr->HeaderChecksum);
ovsUserStats.ipCsum++;
}
ASSERT(elem->hdrInfo.tcpCsumNeeded == 0 &&
elem->hdrInfo.udpCsumNeeded == 0);
/*
* Fow now, we will not do verification
* There is no correctness issue here.
* XXX
*/
/*
* calculate TCP/UDP pseudo checksum
*/
if (isRecv && csumInfo.Receive.TcpChecksumValueInvalid) {
/*
* Only this case, we need to reclaculate pseudo checksum
* all other cases, it is assumed the pseudo checksum is
* filled already.
*
*/
PTCP_HDR tcpHdr = (PTCP_HDR)(dst + hdrInfo->l4Offset);
if (hdrInfo->isIPv4) {
PIPV4_HEADER ipHdr = (PIPV4_HEADER)(dst + hdrInfo->l3Offset);
elem->hdrInfo.l4PayLoad = (UINT16)(ntohs(ipHdr->TotalLength) -
(ipHdr->HeaderLength << 2));
tcpHdr->th_sum =
IPPseudoChecksum((UINT32 *)&ipHdr->SourceAddress,
(UINT32 *)&ipHdr->DestinationAddress,
IPPROTO_TCP, elem->hdrInfo.l4PayLoad);
} else {
PIPV6_HEADER ipv6Hdr = (PIPV6_HEADER)(dst + hdrInfo->l3Offset);
elem->hdrInfo.l4PayLoad =
(UINT16)(ntohs(ipv6Hdr->PayloadLength) +
hdrInfo->l3Offset + sizeof(IPV6_HEADER) -
hdrInfo->l4Offset);
ASSERT(hdrInfo->isIPv6);
tcpHdr->th_sum =
IPv6PseudoChecksum((UINT32 *)&ipv6Hdr->SourceAddress,
(UINT32 *)&ipv6Hdr->DestinationAddress,
IPPROTO_TCP, elem->hdrInfo.l4PayLoad);
}
elem->hdrInfo.tcpCsumNeeded = 1;
ovsUserStats.recalTcpCsum++;
} else if (!isRecv) {
if (csumInfo.Transmit.TcpChecksum) {
elem->hdrInfo.tcpCsumNeeded = 1;
} else if (csumInfo.Transmit.UdpChecksum) {
elem->hdrInfo.udpCsumNeeded = 1;
}
if (elem->hdrInfo.tcpCsumNeeded || elem->hdrInfo.udpCsumNeeded) {
#ifdef DBG
UINT16 sum, *ptr;
UINT8 proto =
elem->hdrInfo.tcpCsumNeeded ? IPPROTO_TCP : IPPROTO_UDP;
#endif
if (hdrInfo->isIPv4) {
PIPV4_HEADER ipHdr = (PIPV4_HEADER)(dst + hdrInfo->l3Offset);
elem->hdrInfo.l4PayLoad = (UINT16)(ntohs(ipHdr->TotalLength) -
(ipHdr->HeaderLength << 2));
#ifdef DBG
sum = IPPseudoChecksum((UINT32 *)&ipHdr->SourceAddress,
(UINT32 *)&ipHdr->DestinationAddress,
proto, elem->hdrInfo.l4PayLoad);
#endif
} else {
PIPV6_HEADER ipv6Hdr = (PIPV6_HEADER)(dst +
hdrInfo->l3Offset);
elem->hdrInfo.l4PayLoad =
(UINT16)(ntohs(ipv6Hdr->PayloadLength) +
hdrInfo->l3Offset + sizeof(IPV6_HEADER) -
hdrInfo->l4Offset);
ASSERT(hdrInfo->isIPv6);
#ifdef DBG
sum = IPv6PseudoChecksum((UINT32 *)&ipv6Hdr->SourceAddress,
(UINT32 *)&ipv6Hdr->DestinationAddress,
proto, elem->hdrInfo.l4PayLoad);
#endif
}
#ifdef DBG
ptr = (UINT16 *)(dst + hdrInfo->l4Offset +
(elem->hdrInfo.tcpCsumNeeded ?
TCP_CSUM_OFFSET : UDP_CSUM_OFFSET));
ASSERT(*ptr == sum);
#endif
}
}
/*
* Finally insert VLAN tag
*/
if (extraLen) {
dst = elem->packet.data + userDataLen;
src = dst + extraLen;
((UINT32 *)dst)[0] = ((UINT32 *)src)[0];
((UINT32 *)dst)[1] = ((UINT32 *)src)[1];
((UINT32 *)dst)[2] = ((UINT32 *)src)[2];
dst += 12;
((UINT16 *)dst)[0] = htons(0x8100);
((UINT16 *)dst)[1] = htons(vlanInfo.TagHeader.VlanId |
(vlanInfo.TagHeader.UserPriority << 13));
elem->hdrInfo.l3Offset += VLAN_TAG_SIZE;
elem->hdrInfo.l4Offset += VLAN_TAG_SIZE;
ovsUserStats.vlanInsert++;
}

return elem;
}


VOID
OvsQueuePackets(UINT32 queueId,
PLIST_ENTRY packetList,
Expand Down Expand Up @@ -819,12 +578,11 @@ OvsQueuePackets(UINT32 queueId,
*----------------------------------------------------------------------------
*/
NTSTATUS
OvsCreateAndAddPackets(UINT32 queueId,
PVOID userData,
OvsCreateAndAddPackets(PVOID userData,
UINT32 userDataLen,
UINT32 cmd,
UINT32 inPort,
OvsIPv4TunnelKey *tunnelKey,
OvsFlowKey *key,
PNET_BUFFER_LIST nbl,
BOOLEAN isRecv,
POVS_PACKET_HDR_INFO hdrInfo,
Expand Down Expand Up @@ -859,8 +617,8 @@ OvsCreateAndAddPackets(UINT32 queueId,

nb = NET_BUFFER_LIST_FIRST_NB(nbl);
while (nb) {
elem = OvsCreateQueuePacket(queueId, userData, userDataLen,
cmd, inPort, tunnelKey, nbl, nb,
elem = OvsCreateQueueNlPacket(userData, userDataLen,
cmd, inPort, key, nbl, nb,
isRecv, hdrInfo);
if (elem) {
InsertTailList(list, &elem->link);
Expand Down
22 changes: 10 additions & 12 deletions datapath-windows/ovsext/User.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,24 +71,22 @@ VOID OvsUserCleanup();

VOID OvsCleanupPacketQueue(struct _OVS_OPEN_INSTANCE *instance);

POVS_PACKET_QUEUE_ELEM OvsCreateQueuePacket(UINT32 queueId,
PVOID userData,
UINT32 userDataLen,
UINT32 cmd, UINT32 inPort,
OvsIPv4TunnelKey *tunnelKey,
PNET_BUFFER_LIST nbl,
PNET_BUFFER nb,
BOOLEAN isRecv,
POVS_PACKET_HDR_INFO hdrInfo);
POVS_PACKET_QUEUE_ELEM OvsCreateQueueNlPacket(PVOID userData,
UINT32 userDataLen,
UINT32 cmd, UINT32 inPort,
OvsFlowKey *key,
PNET_BUFFER_LIST nbl,
PNET_BUFFER nb,
BOOLEAN isRecv,
POVS_PACKET_HDR_INFO hdrInfo);

VOID OvsQueuePackets(UINT32 queueId, PLIST_ENTRY packetList,
UINT32 numElems);
NTSTATUS OvsCreateAndAddPackets(UINT32 queueId,
PVOID userData,
NTSTATUS OvsCreateAndAddPackets(PVOID userData,
UINT32 userDataLen,
UINT32 cmd,
UINT32 inPort,
OvsIPv4TunnelKey *tunnelKey,
OvsFlowKey *key,
PNET_BUFFER_LIST nbl,
BOOLEAN isRecv,
POVS_PACKET_HDR_INFO hdrInfo,
Expand Down

0 comments on commit 640ebde

Please sign in to comment.