Skip to content

Commit

Permalink
datapath-windows: Update flow key in SET action
Browse files Browse the repository at this point in the history
The flow key is not updated when process OVS_ACTION_ATTR_SET action.
It will impact follow-up actions, such as, conntrack module cannot
find created conntrack entry if passing old flow key to it.

Reported-by: Rui Cao <rcao@vmware.com>
Signed-off-by: Jinjun Gao <jinjung@vmware.com>
Signed-off-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com>
  • Loading branch information
Jinjun Gao authored and Alin Gabriel Serdean committed Jul 31, 2020
1 parent 2db927b commit c702068
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 7 deletions.
31 changes: 24 additions & 7 deletions datapath-windows/ovsext/Actions.c
Expand Up @@ -1259,6 +1259,7 @@ OvsActionMplsPush(OvsForwardingContext *ovsFwdCtx,
*/
static __inline NDIS_STATUS
OvsUpdateEthHeader(OvsForwardingContext *ovsFwdCtx,
OvsFlowKey *key,
const struct ovs_key_ethernet *ethAttr)
{
PNET_BUFFER curNb;
Expand All @@ -1285,9 +1286,11 @@ OvsUpdateEthHeader(OvsForwardingContext *ovsFwdCtx,
}
ethHdr = (EthHdr *)(bufferStart + NET_BUFFER_CURRENT_MDL_OFFSET(curNb));

RtlCopyMemory(ethHdr->Destination, ethAttr->eth_dst,
sizeof ethHdr->Destination);
RtlCopyMemory(ethHdr->Source, ethAttr->eth_src, sizeof ethHdr->Source);
RtlCopyMemory(ethHdr->Destination, ethAttr->eth_dst, ETH_ADDR_LENGTH);
RtlCopyMemory(ethHdr->Source, ethAttr->eth_src, ETH_ADDR_LENGTH);
/* Update l2 flow key */
RtlCopyMemory(key->l2.dlDst, ethAttr->eth_dst, ETH_ADDR_LENGTH);
RtlCopyMemory(key->l2.dlSrc, ethAttr->eth_src, ETH_ADDR_LENGTH);

return NDIS_STATUS_SUCCESS;
}
Expand Down Expand Up @@ -1376,6 +1379,7 @@ PUINT8 OvsGetHeaderBySize(OvsForwardingContext *ovsFwdCtx,
*/
NDIS_STATUS
OvsUpdateUdpPorts(OvsForwardingContext *ovsFwdCtx,
OvsFlowKey *key,
const struct ovs_key_udp *udpAttr)
{
PUINT8 bufferStart;
Expand All @@ -1400,15 +1404,19 @@ OvsUpdateUdpPorts(OvsForwardingContext *ovsFwdCtx,
udpHdr->check = ChecksumUpdate16(udpHdr->check, udpHdr->source,
udpAttr->udp_src);
udpHdr->source = udpAttr->udp_src;
key->ipKey.l4.tpSrc = udpAttr->udp_src;
}
if (udpHdr->dest != udpAttr->udp_dst) {
udpHdr->check = ChecksumUpdate16(udpHdr->check, udpHdr->dest,
udpAttr->udp_dst);
udpHdr->dest = udpAttr->udp_dst;
key->ipKey.l4.tpDst = udpAttr->udp_dst;
}
} else {
udpHdr->source = udpAttr->udp_src;
key->ipKey.l4.tpSrc = udpAttr->udp_src;
udpHdr->dest = udpAttr->udp_dst;
key->ipKey.l4.tpDst = udpAttr->udp_dst;
}

return NDIS_STATUS_SUCCESS;
Expand All @@ -1423,6 +1431,7 @@ OvsUpdateUdpPorts(OvsForwardingContext *ovsFwdCtx,
*/
NDIS_STATUS
OvsUpdateTcpPorts(OvsForwardingContext *ovsFwdCtx,
OvsFlowKey *key,
const struct ovs_key_tcp *tcpAttr)
{
PUINT8 bufferStart;
Expand All @@ -1447,11 +1456,13 @@ OvsUpdateTcpPorts(OvsForwardingContext *ovsFwdCtx,
tcpHdr->check = ChecksumUpdate16(tcpHdr->check, tcpHdr->source,
tcpAttr->tcp_src);
tcpHdr->source = tcpAttr->tcp_src;
key->ipKey.l4.tpSrc = tcpAttr->tcp_src;
}
if (tcpHdr->dest != tcpAttr->tcp_dst) {
tcpHdr->check = ChecksumUpdate16(tcpHdr->check, tcpHdr->dest,
tcpAttr->tcp_dst);
tcpHdr->dest = tcpAttr->tcp_dst;
key->ipKey.l4.tpDst = tcpAttr->tcp_dst;
}

return NDIS_STATUS_SUCCESS;
Expand Down Expand Up @@ -1579,6 +1590,7 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx,
*/
NDIS_STATUS
OvsUpdateIPv4Header(OvsForwardingContext *ovsFwdCtx,
OvsFlowKey *key,
const struct ovs_key_ipv4 *ipAttr)
{
PUINT8 bufferStart;
Expand Down Expand Up @@ -1632,6 +1644,7 @@ OvsUpdateIPv4Header(OvsForwardingContext *ovsFwdCtx,
ipAttr->ipv4_src);
}
ipHdr->saddr = ipAttr->ipv4_src;
key->ipKey.nwSrc = ipAttr->ipv4_src;
}
if (ipHdr->daddr != ipAttr->ipv4_dst) {
if (tcpHdr) {
Expand All @@ -1647,6 +1660,7 @@ OvsUpdateIPv4Header(OvsForwardingContext *ovsFwdCtx,
ipAttr->ipv4_dst);
}
ipHdr->daddr = ipAttr->ipv4_dst;
key->ipKey.nwDst = ipAttr->ipv4_dst;
}
if (ipHdr->protocol != ipAttr->ipv4_proto) {
UINT16 oldProto = (ipHdr->protocol << 16) & 0xff00;
Expand All @@ -1661,6 +1675,7 @@ OvsUpdateIPv4Header(OvsForwardingContext *ovsFwdCtx,
ipHdr->check = ChecksumUpdate16(ipHdr->check, oldProto, newProto);
}
ipHdr->protocol = ipAttr->ipv4_proto;
key->ipKey.nwProto = ipAttr->ipv4_proto;
}
if (ipHdr->ttl != ipAttr->ipv4_ttl) {
UINT16 oldTtl = (ipHdr->ttl) & 0xff;
Expand All @@ -1669,6 +1684,7 @@ OvsUpdateIPv4Header(OvsForwardingContext *ovsFwdCtx,
ipHdr->check = ChecksumUpdate16(ipHdr->check, oldTtl, newTtl);
}
ipHdr->ttl = ipAttr->ipv4_ttl;
key->ipKey.nwTtl = ipAttr->ipv4_ttl;
}

return NDIS_STATUS_SUCCESS;
Expand All @@ -1691,12 +1707,12 @@ OvsExecuteSetAction(OvsForwardingContext *ovsFwdCtx,

switch (type) {
case OVS_KEY_ATTR_ETHERNET:
status = OvsUpdateEthHeader(ovsFwdCtx,
status = OvsUpdateEthHeader(ovsFwdCtx, key,
NlAttrGetUnspec(a, sizeof(struct ovs_key_ethernet)));
break;

case OVS_KEY_ATTR_IPV4:
status = OvsUpdateIPv4Header(ovsFwdCtx,
status = OvsUpdateIPv4Header(ovsFwdCtx, key,
NlAttrGetUnspec(a, sizeof(struct ovs_key_ipv4)));
break;

Expand All @@ -1709,16 +1725,17 @@ OvsExecuteSetAction(OvsForwardingContext *ovsFwdCtx,
status = SUCCEEDED(convertStatus) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE;
ASSERT(status == NDIS_STATUS_SUCCESS);
RtlCopyMemory(&ovsFwdCtx->tunKey, &tunKey, sizeof ovsFwdCtx->tunKey);
RtlCopyMemory(&key->tunKey, &tunKey, sizeof key->tunKey);
break;
}

case OVS_KEY_ATTR_UDP:
status = OvsUpdateUdpPorts(ovsFwdCtx,
status = OvsUpdateUdpPorts(ovsFwdCtx, key,
NlAttrGetUnspec(a, sizeof(struct ovs_key_udp)));
break;

case OVS_KEY_ATTR_TCP:
status = OvsUpdateTcpPorts(ovsFwdCtx,
status = OvsUpdateTcpPorts(ovsFwdCtx, key,
NlAttrGetUnspec(a, sizeof(struct ovs_key_tcp)));
break;

Expand Down
3 changes: 3 additions & 0 deletions datapath-windows/ovsext/Actions.h
Expand Up @@ -115,14 +115,17 @@ PUINT8 OvsGetHeaderBySize(OvsForwardingContext *ovsFwdCtx,

NDIS_STATUS
OvsUpdateUdpPorts(OvsForwardingContext *ovsFwdCtx,
OvsFlowKey *key,
const struct ovs_key_udp *udpAttr);

NDIS_STATUS
OvsUpdateTcpPorts(OvsForwardingContext *ovsFwdCtx,
OvsFlowKey *key,
const struct ovs_key_tcp *tcpAttr);

NDIS_STATUS
OvsUpdateIPv4Header(OvsForwardingContext *ovsFwdCtx,
OvsFlowKey *key,
const struct ovs_key_ipv4 *ipAttr);

NDIS_STATUS
Expand Down

0 comments on commit c702068

Please sign in to comment.