Functionality for vport dump.
Later, when we will add more netlink dump commands, some common code will need
to be split to functions.
Notes:
a) the current implementation of vport assumes the datapath feature
multiple upcall pids is not used. A single upcall pid is used now.
c) the vxlan destination udp port is currently a constant. When it will become
configurable, the vport options netlink attribute will become relevant.
Signed-off-by: Samuel Ghinet sghi...@cloudbasesolutions.com
Acked-by: Alin Gabriel Serdean aserd...@cloudbasesolutions.com
Acked-by: Nithin Raju nit...@vmware.com
---
datapath-windows/ovsext/Datapath.c | 273 -
datapath-windows/ovsext/Vport.h| 11 +-
2 files changed, 276 insertions(+), 8 deletions(-)
diff --git a/datapath-windows/ovsext/Datapath.c
b/datapath-windows/ovsext/Datapath.c
index 0dfdd57..25d6f87 100644
--- a/datapath-windows/ovsext/Datapath.c
+++ b/datapath-windows/ovsext/Datapath.c
@@ -99,7 +99,8 @@ static NetlinkCmdHandler OvsGetPidCmdHandler,
OvsGetDpCmdHandler,
OvsPendEventCmdHandler,
OvsSubscribeEventCmdHandler,
- OvsSetDpCmdHandler;
+ OvsSetDpCmdHandler,
+ OvsGetVportCmdHandler;
static NTSTATUS HandleGetDpTransaction(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
UINT32 *replyLen);
@@ -180,14 +181,22 @@ NETLINK_FAMILY nlPacketFamilyOps = {
};
/* Netlink vport family. */
-/* XXX: Add commands here. */
+NETLINK_CMD nlVportFamilyCmdOps[] = {
+{ .cmd = OVS_VPORT_CMD_GET,
+ .handler = OvsGetVportCmdHandler,
+ .supportedDevOp = OVS_WRITE_DEV_OP | OVS_READ_DEV_OP |
+OVS_TRANSACTION_DEV_OP,
+ .validateDpIndex = TRUE
+}
+};
+
NETLINK_FAMILY nlVportFamilyOps = {
.name = OVS_VPORT_FAMILY,
.id = OVS_WIN_NL_VPORT_FAMILY_ID,
.version = OVS_VPORT_VERSION,
.maxAttr = OVS_VPORT_ATTR_MAX,
-.cmds = NULL, /* XXX: placeholder. */
-.opsCount = 0
+.cmds = nlVportFamilyCmdOps,
+.opsCount = ARRAY_SIZE(nlVportFamilyCmdOps)
};
/* Netlink flow family. */
@@ -691,10 +700,11 @@ OvsDeviceControl(PDEVICE_OBJECT deviceObject,
break;
case OVS_WIN_NL_PACKET_FAMILY_ID:
case OVS_WIN_NL_FLOW_FAMILY_ID:
-case OVS_WIN_NL_VPORT_FAMILY_ID:
status = STATUS_NOT_IMPLEMENTED;
goto done;
-
+case OVS_WIN_NL_VPORT_FAMILY_ID:
+nlFamilyOps = nlVportFamilyOps;
+break;
default:
status = STATUS_INVALID_PARAMETER;
goto done;
@@ -1179,6 +1189,257 @@ OvsSetupDumpStart(POVS_USER_PARAMS_CONTEXT usrParamsCtx)
return InitUserDumpState(instance, msgIn);
}
+static VOID
+BuildMsgOut(POVS_MESSAGE msgIn, POVS_MESSAGE msgOut, UINT16 type,
+ UINT32 length, UINT16 flags)
+{
+msgOut-nlMsg.nlmsgType = type;
+msgOut-nlMsg.nlmsgFlags = flags;
+msgOut-nlMsg.nlmsgSeq = msgIn-nlMsg.nlmsgSeq;
+msgOut-nlMsg.nlmsgPid = msgIn-nlMsg.nlmsgPid;
+msgOut-nlMsg.nlmsgLen = length;
+
+msgOut-genlMsg.cmd = msgIn-genlMsg.cmd;
+msgOut-genlMsg.version = nlDatapathFamilyOps.version;
+msgOut-genlMsg.reserved = 0;
+}
+
+static VOID
+BuildReplyMsgFromMsgIn(POVS_MESSAGE msgIn, POVS_MESSAGE msgOut, UINT16 flags)
+{
+BuildMsgOut(msgIn, msgOut, msgIn-nlMsg.nlmsgType, sizeof(OVS_MESSAGE),
+flags);
+}
+
+static NTSTATUS
+OvsCreateMsgFromVport(POVS_VPORT_ENTRY vport,
+ POVS_MESSAGE msgIn,
+ PVOID outBuffer,
+ UINT32 outBufLen,
+ int dpIfIndex)
+{
+NL_BUFFER nlBuffer;
+OVS_VPORT_FULL_STATS vportStats;
+BOOLEAN ok;
+OVS_MESSAGE msgOut;
+PNL_MSG_HDR nlMsg;
+
+NlBufInit(nlBuffer, outBuffer, outBufLen);
+
+BuildReplyMsgFromMsgIn(msgIn, msgOut, NLM_F_MULTI);
+msgOut.ovsHdr.dp_ifindex = dpIfIndex;
+
+ok = NlMsgPutHead(nlBuffer, (PCHAR)msgOut, sizeof msgOut);
+if (!ok) {
+return STATUS_INSUFFICIENT_RESOURCES;
+}
+
+ok = NlMsgPutTailU32(nlBuffer, OVS_VPORT_ATTR_PORT_NO, vport-portNo);
+if (!ok) {
+return STATUS_INSUFFICIENT_RESOURCES;
+}
+
+ok = NlMsgPutTailU32(nlBuffer, OVS_VPORT_ATTR_TYPE, vport-ovsType);
+if (!ok) {
+return STATUS_INSUFFICIENT_RESOURCES;
+}
+
+ok = NlMsgPutTailString(nlBuffer, OVS_VPORT_ATTR_NAME, vport-ovsName);
+if (!ok) {
+return STATUS_INSUFFICIENT_RESOURCES;
+}
+
+/*
+ * XXX: when we implement OVS_DP_ATTR_USER_FEATURES in datapath,
+ * we'll need to check the OVS_DP_F_VPORT_PIDS flag: if it is set,
+ * it means we have an array of pids, instead of a single pid.
+ * ATM we assume we have one pid only.
+*/
+
+ok = NlMsgPutTailU32(nlBuffer, OVS_VPORT_ATTR_UPCALL_PID,
+ vport-upcallPid);
+if (!ok) {
+