summaryrefslogtreecommitdiff
path: root/datapath-windows/ovsext/Flow.c
diff options
context:
space:
mode:
Diffstat (limited to 'datapath-windows/ovsext/Flow.c')
-rw-r--r--datapath-windows/ovsext/Flow.c126
1 files changed, 113 insertions, 13 deletions
diff --git a/datapath-windows/ovsext/Flow.c b/datapath-windows/ovsext/Flow.c
index f8809876e..7994786d2 100644
--- a/datapath-windows/ovsext/Flow.c
+++ b/datapath-windows/ovsext/Flow.c
@@ -115,7 +115,7 @@ const NL_POLICY nlFlowKeyPolicy[] = {
[OVS_KEY_ATTR_PRIORITY] = {.type = NL_A_UNSPEC, .minLen = 4,
.maxLen = 4, .optional = TRUE},
[OVS_KEY_ATTR_IN_PORT] = {.type = NL_A_UNSPEC, .minLen = 4,
- .maxLen = 4, .optional = FALSE},
+ .maxLen = 4, .optional = TRUE},
[OVS_KEY_ATTR_ETHERNET] = {.type = NL_A_UNSPEC,
.minLen = sizeof(struct ovs_key_ethernet),
.maxLen = sizeof(struct ovs_key_ethernet),
@@ -457,6 +457,7 @@ _FlowNlGetCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
NL_BUFFER nlBuf;
PNL_ATTR keyAttrs[__OVS_KEY_ATTR_MAX];
PNL_ATTR tunnelAttrs[__OVS_TUNNEL_KEY_ATTR_MAX];
+ PNL_ATTR encapAttrs[__OVS_KEY_ATTR_MAX];
NlBufInit(&nlBuf, usrParamsCtx->outputBuffer,
usrParamsCtx->outputLength);
@@ -464,6 +465,7 @@ _FlowNlGetCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
RtlZeroMemory(&getOutput, sizeof(OvsFlowGetOutput));
UINT32 keyAttrOffset = 0;
UINT32 tunnelKeyAttrOffset = 0;
+ UINT32 encapOffset = 0;
BOOLEAN ok;
NL_ERROR nlError = NL_ERROR_SUCCESS;
@@ -503,6 +505,23 @@ _FlowNlGetCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
goto done;
}
+ if (keyAttrs[OVS_KEY_ATTR_ENCAP]) {
+ encapOffset = (UINT32)((PCHAR) (keyAttrs[OVS_KEY_ATTR_ENCAP])
+ - (PCHAR)nlMsgHdr);
+
+ if ((NlAttrParseNested(nlMsgHdr, encapOffset,
+ NlAttrLen(keyAttrs[OVS_KEY_ATTR_ENCAP]),
+ nlFlowKeyPolicy,
+ ARRAY_SIZE(nlFlowKeyPolicy),
+ encapAttrs, ARRAY_SIZE(encapAttrs)))
+ != TRUE) {
+ OVS_LOG_ERROR("Encap Key Attr Parsing failed for msg: %p",
+ nlMsgHdr);
+ rc = STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+ }
+
if (keyAttrs[OVS_KEY_ATTR_TUNNEL]) {
tunnelKeyAttrOffset = (UINT32)((PCHAR)
(keyAttrs[OVS_KEY_ATTR_TUNNEL])
@@ -524,6 +543,12 @@ _FlowNlGetCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
_MapKeyAttrToFlowPut(keyAttrs, tunnelAttrs,
&(getInput.key));
+ ASSERT(keyAttrs[OVS_KEY_ATTR_IN_PORT]);
+
+ if (encapOffset) {
+ _MapKeyAttrToFlowPut(encapAttrs, tunnelAttrs,
+ &(getInput.key));
+ }
getInput.dpNo = ovsHdr->dp_ifindex;
getInput.getFlags = FLOW_GET_STATS | FLOW_GET_ACTIONS;
@@ -855,7 +880,7 @@ MapFlowKeyToNlKey(PNL_BUFFER nlBuf,
{
NTSTATUS rc = STATUS_SUCCESS;
struct ovs_key_ethernet ethKey;
- UINT32 offset = 0;
+ UINT32 offset = 0, encap_offset = 0;
offset = NlMsgStartNested(nlBuf, keyType);
if (!offset) {
@@ -924,17 +949,34 @@ MapFlowKeyToNlKey(PNL_BUFFER nlBuf,
}
if (!NlMsgPutTailU16(nlBuf, OVS_KEY_ATTR_ETHERTYPE,
- flowKey->l2.dlType)) {
+ flowKey->l2.vlanKey.vlanTci == 0 ? flowKey->l2.dlType :
+ flowKey->l2.vlanKey.vlanTpid)) {
rc = STATUS_UNSUCCESSFUL;
goto done;
}
- if (flowKey->l2.vlanTci) {
+ if (flowKey->l2.vlanKey.vlanTci ||
+ flowKey->l2.dlType == ETH_TYPE_802_1PQ) {
if (!NlMsgPutTailU16(nlBuf, OVS_KEY_ATTR_VLAN,
- flowKey->l2.vlanTci)) {
+ flowKey->l2.vlanKey.vlanTci)) {
+ rc = STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Add encap attributes. */
+ encap_offset = NlMsgStartNested(nlBuf, OVS_KEY_ATTR_ENCAP);
+ if (!encap_offset) {
+ /* Starting the nested attribute failed. */
rc = STATUS_UNSUCCESSFUL;
goto done;
}
+
+ /* Add packet Ethernet Type*/
+ if (!NlMsgPutTailU16(nlBuf, OVS_KEY_ATTR_ETHERTYPE,
+ flowKey->l2.dlType)) {
+ rc = STATUS_UNSUCCESSFUL;
+ goto encap;
+ }
}
/* ==== L3 + L4 ==== */
@@ -982,6 +1024,10 @@ MapFlowKeyToNlKey(PNL_BUFFER nlBuf,
goto done;
}
}
+encap:
+ if (encap_offset) {
+ NlMsgEndNested(nlBuf, encap_offset);
+ }
done:
NlMsgEndNested(nlBuf, offset);
@@ -1336,9 +1382,11 @@ _MapNlToFlowPut(POVS_MESSAGE msgIn, PNL_ATTR keyAttr,
UINT32 keyAttrOffset = (UINT32)((PCHAR)keyAttr - (PCHAR)nlMsgHdr);
UINT32 tunnelKeyAttrOffset;
+ UINT32 encapOffset = 0;
PNL_ATTR keyAttrs[__OVS_KEY_ATTR_MAX] = {NULL};
PNL_ATTR tunnelAttrs[__OVS_TUNNEL_KEY_ATTR_MAX] = {NULL};
+ PNL_ATTR encapAttrs[__OVS_KEY_ATTR_MAX] = { NULL };
/* Get flow keys attributes */
if ((NlAttrParseNested(nlMsgHdr, keyAttrOffset, NlAttrLen(keyAttr),
@@ -1351,6 +1399,23 @@ _MapNlToFlowPut(POVS_MESSAGE msgIn, PNL_ATTR keyAttr,
goto done;
}
+ if (keyAttrs[OVS_KEY_ATTR_ENCAP]) {
+ encapOffset = (UINT32)((PCHAR)(keyAttrs[OVS_KEY_ATTR_ENCAP])
+ - (PCHAR)nlMsgHdr);
+
+ if ((NlAttrParseNested(nlMsgHdr, encapOffset,
+ NlAttrLen(keyAttrs[OVS_KEY_ATTR_ENCAP]),
+ nlFlowKeyPolicy,
+ ARRAY_SIZE(nlFlowKeyPolicy),
+ encapAttrs, ARRAY_SIZE(encapAttrs)))
+ != TRUE) {
+ OVS_LOG_ERROR("Encap Key Attr Parsing failed for msg: %p",
+ nlMsgHdr);
+ rc = STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+ }
+
if (keyAttrs[OVS_KEY_ATTR_TUNNEL]) {
tunnelKeyAttrOffset = (UINT32)((PCHAR)
(keyAttrs[OVS_KEY_ATTR_TUNNEL])
@@ -1372,6 +1437,12 @@ _MapNlToFlowPut(POVS_MESSAGE msgIn, PNL_ATTR keyAttr,
_MapKeyAttrToFlowPut(keyAttrs, tunnelAttrs,
&(mappedFlow->key));
+ ASSERT(keyAttrs[OVS_KEY_ATTR_IN_PORT]);
+
+ if (encapOffset) {
+ _MapKeyAttrToFlowPut(encapAttrs, tunnelAttrs,
+ &(mappedFlow->key));
+ }
/* Map the action */
if (actionAttr) {
@@ -1469,7 +1540,9 @@ _MapKeyAttrToFlowPut(PNL_ATTR *keyAttrs,
}
/* ===== L2 headers ===== */
- destKey->l2.inPort = NlAttrGetU32(keyAttrs[OVS_KEY_ATTR_IN_PORT]);
+ if (keyAttrs[OVS_KEY_ATTR_IN_PORT]) {
+ destKey->l2.inPort = NlAttrGetU32(keyAttrs[OVS_KEY_ATTR_IN_PORT]);
+ }
if (keyAttrs[OVS_KEY_ATTR_ETHERNET]) {
const struct ovs_key_ethernet *eth_key;
@@ -1488,7 +1561,11 @@ _MapKeyAttrToFlowPut(PNL_ATTR *keyAttrs,
}
if (keyAttrs[OVS_KEY_ATTR_VLAN]) {
- destKey->l2.vlanTci = NlAttrGetU16(keyAttrs[OVS_KEY_ATTR_VLAN]);
+ destKey->l2.vlanKey.vlanTci = NlAttrGetU16(keyAttrs[OVS_KEY_ATTR_VLAN]);
+ if (destKey->l2.vlanKey.vlanTci != 0) {
+ /* set TPID to dlType. */
+ destKey->l2.vlanKey.vlanTpid = destKey->l2.dlType;
+ }
}
/* ==== L3 + L4. ==== */
@@ -2267,17 +2344,20 @@ OvsExtractFlow(const NET_BUFFER_LIST *packet,
if (vlanTagValue) {
PNDIS_NET_BUFFER_LIST_8021Q_INFO vlanTag =
(PNDIS_NET_BUFFER_LIST_8021Q_INFO)(PVOID *)&vlanTagValue;
- flow->l2.vlanTci = htons(vlanTag->TagHeader.VlanId | OVSWIN_VLAN_CFI |
- (vlanTag->TagHeader.UserPriority << 13));
+ flow->l2.vlanKey.vlanTci = htons(vlanTag->TagHeader.VlanId | OVSWIN_VLAN_CFI |
+ (vlanTag->TagHeader.UserPriority << 13));
+ flow->l2.vlanKey.vlanTpid = htons(ETH_TYPE_802_1PQ);
} else {
if (eth->dix.typeNBO == ETH_TYPE_802_1PQ_NBO) {
Eth_802_1pq_Tag *tag= (Eth_802_1pq_Tag *)&eth->dix.typeNBO;
- flow->l2.vlanTci = ((UINT16)tag->priority << 13) |
- OVSWIN_VLAN_CFI |
- ((UINT16)tag->vidHi << 8) | tag->vidLo;
+ flow->l2.vlanKey.vlanTci = ((UINT16)tag->priority << 13) |
+ OVSWIN_VLAN_CFI | ((UINT16)tag->vidHi << 8) | tag->vidLo;
+ flow->l2.vlanKey.vlanTpid = htons(ETH_TYPE_802_1PQ);
offset = sizeof (Eth_802_1pq_Tag);
} else {
- flow->l2.vlanTci = 0;
+ /* Initialize vlan key to 0 for non vlan packets. */
+ flow->l2.vlanKey.vlanTci = 0;
+ flow->l2.vlanKey.vlanTpid = 0;
}
/*
* XXX Please note after this point, src mac and dst mac should
@@ -3095,7 +3175,9 @@ OvsProbeSupportedFeature(POVS_MESSAGE msgIn,
PNL_MSG_HDR nlMsgHdr = &(msgIn->nlMsg);
UINT32 keyAttrOffset = (UINT32)((PCHAR)keyAttr - (PCHAR)nlMsgHdr);
+ UINT32 encapOffset = 0;
PNL_ATTR keyAttrs[__OVS_KEY_ATTR_MAX] = { NULL };
+ PNL_ATTR encapAttrs[__OVS_KEY_ATTR_MAX] = { NULL };
/* Get flow keys attributes */
if ((NlAttrParseNested(nlMsgHdr, keyAttrOffset, NlAttrLen(keyAttr),
@@ -3108,6 +3190,24 @@ OvsProbeSupportedFeature(POVS_MESSAGE msgIn,
goto done;
}
+ if (keyAttrs[OVS_KEY_ATTR_ENCAP]) {
+ encapOffset = (UINT32)((PCHAR)(keyAttrs[OVS_KEY_ATTR_ENCAP])
+ - (PCHAR)nlMsgHdr);
+
+ /* Get tunnel keys attributes */
+ if ((NlAttrParseNested(nlMsgHdr, encapOffset,
+ NlAttrLen(keyAttrs[OVS_KEY_ATTR_ENCAP]),
+ nlFlowKeyPolicy,
+ ARRAY_SIZE(nlFlowKeyPolicy),
+ encapAttrs, ARRAY_SIZE(encapAttrs)))
+ != TRUE) {
+ OVS_LOG_ERROR("Encap Key Attr Parsing failed for msg: %p",
+ nlMsgHdr);
+ status = STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+ }
+
if (keyAttrs[OVS_KEY_ATTR_MPLS] &&
keyAttrs[OVS_KEY_ATTR_ETHERTYPE]) {
ovs_be16 ethType = NlAttrGetU16(keyAttrs[OVS_KEY_ATTR_ETHERTYPE]);