summaryrefslogtreecommitdiff
path: root/datapath-windows/ovsext
diff options
context:
space:
mode:
authorAnkur Sharma <ankursharma@vmware.com>2014-09-26 17:32:59 -0700
committerBen Pfaff <blp@nicira.com>2014-09-29 09:03:42 -0700
commit0d9bd68b7b30a83d601cca2040702894a95b2b5a (patch)
tree31ad6e66524c03af410846104544c39d44f981ba /datapath-windows/ovsext
parent5b2249547f91337ca1e5150ed9dbd2d9af58165b (diff)
downloadopenvswitch-0d9bd68b7b30a83d601cca2040702894a95b2b5a.tar.gz
datapath-windows/Flow.c : Basic support for add-flow.
This patch covers basic changes in registering add flow handler. And declaring FLOW related attribute parsing policies. Signed-off-by: Ankur Sharma <ankursharma@vmware.com> Acked-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com> Acked-by: Eitan Eliahu <eliahue@vmware.com> Acked-by: Nithin Raju <nithin@vmware.com> Acked-by: Samuel Ghinet <sghinet@cloudbasesolutions.com> Tested-by: Ankur Sharma <ankursharma@vmware.com> Signed-off-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'datapath-windows/ovsext')
-rw-r--r--datapath-windows/ovsext/Datapath.c18
-rw-r--r--datapath-windows/ovsext/Flow.c155
-rw-r--r--datapath-windows/ovsext/Flow.h5
3 files changed, 174 insertions, 4 deletions
diff --git a/datapath-windows/ovsext/Datapath.c b/datapath-windows/ovsext/Datapath.c
index 6319542b6..6174a85d8 100644
--- a/datapath-windows/ovsext/Datapath.c
+++ b/datapath-windows/ovsext/Datapath.c
@@ -207,14 +207,22 @@ NETLINK_FAMILY nlVportFamilyOps = {
};
/* Netlink flow family. */
-/* XXX: Add commands here. */
+
+NETLINK_CMD nlFlowFamilyCmdOps[] = {
+ { .cmd = OVS_FLOW_CMD_NEW,
+ .handler = OvsFlowNlNewCmdHandler,
+ .supportedDevOp = OVS_TRANSACTION_DEV_OP,
+ .validateDpIndex = TRUE
+ }
+};
+
NETLINK_FAMILY nlFLowFamilyOps = {
.name = OVS_FLOW_FAMILY,
.id = OVS_WIN_NL_FLOW_FAMILY_ID,
.version = OVS_FLOW_VERSION,
.maxAttr = OVS_FLOW_ATTR_MAX,
- .cmds = NULL, /* XXX: placeholder. */
- .opsCount = 0
+ .cmds = nlFlowFamilyCmdOps,
+ .opsCount = ARRAY_SIZE(nlFlowFamilyCmdOps)
};
static NTSTATUS MapIrpOutputBuffer(PIRP irp,
@@ -728,8 +736,10 @@ OvsDeviceControl(PDEVICE_OBJECT deviceObject,
case OVS_WIN_NL_DATAPATH_FAMILY_ID:
nlFamilyOps = &nlDatapathFamilyOps;
break;
- case OVS_WIN_NL_PACKET_FAMILY_ID:
case OVS_WIN_NL_FLOW_FAMILY_ID:
+ nlFamilyOps = &nlFLowFamilyOps;
+ break;
+ case OVS_WIN_NL_PACKET_FAMILY_ID:
status = STATUS_NOT_IMPLEMENTED;
goto done;
case OVS_WIN_NL_VPORT_FAMILY_ID:
diff --git a/datapath-windows/ovsext/Flow.c b/datapath-windows/ovsext/Flow.c
index dae1dca85..fb408dae6 100644
--- a/datapath-windows/ovsext/Flow.c
+++ b/datapath-windows/ovsext/Flow.c
@@ -51,6 +51,161 @@ static VOID __inline *GetStartAddrNBL(const NET_BUFFER_LIST *_pNB);
#define OVS_FLOW_TABLE_MASK (OVS_FLOW_TABLE_SIZE -1)
#define HASH_BUCKET(hash) ((hash) & OVS_FLOW_TABLE_MASK)
+/* Flow family related netlink policies */
+
+/* For Parsing attributes in FLOW_* commands */
+static const NL_POLICY nlFlowPolicy[] = {
+ [OVS_FLOW_ATTR_KEY] = {.type = NL_A_NESTED, .optional = FALSE},
+ [OVS_FLOW_ATTR_MASK] = {.type = NL_A_NESTED, .optional = TRUE},
+ [OVS_FLOW_ATTR_ACTIONS] = {.type = NL_A_NESTED, .optional = TRUE},
+ [OVS_FLOW_ATTR_STATS] = {.type = NL_A_UNSPEC,
+ .minLen = sizeof(struct ovs_flow_stats),
+ .maxLen = sizeof(struct ovs_flow_stats),
+ .optional = TRUE},
+ [OVS_FLOW_ATTR_TCP_FLAGS] = {NL_A_U8, .optional = TRUE},
+ [OVS_FLOW_ATTR_USED] = {NL_A_U64, .optional = TRUE}
+};
+
+/* For Parsing nested OVS_FLOW_ATTR_KEY attributes.
+ * Some of the attributes like OVS_KEY_ATTR_RECIRC_ID
+ * & OVS_KEY_ATTR_MPLS are not supported yet. */
+
+static const NL_POLICY nlFlowKeyPolicy[] = {
+ [OVS_KEY_ATTR_ENCAP] = {.type = NL_A_VAR_LEN, .optional = TRUE},
+ [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},
+ [OVS_KEY_ATTR_ETHERNET] = {.type = NL_A_UNSPEC,
+ .minLen = sizeof(struct ovs_key_ethernet),
+ .maxLen = sizeof(struct ovs_key_ethernet),
+ .optional = FALSE},
+ [OVS_KEY_ATTR_VLAN] = {.type = NL_A_UNSPEC, .minLen = 2,
+ .maxLen = 2, .optional = TRUE},
+ [OVS_KEY_ATTR_ETHERTYPE] = {.type = NL_A_UNSPEC, .minLen = 2,
+ .maxLen = 2, .optional = TRUE},
+ [OVS_KEY_ATTR_IPV4] = {.type = NL_A_UNSPEC,
+ .minLen = sizeof(struct ovs_key_ipv4),
+ .maxLen = sizeof(struct ovs_key_ipv4),
+ .optional = TRUE},
+ [OVS_KEY_ATTR_IPV6] = {.type = NL_A_UNSPEC,
+ .minLen = sizeof(struct ovs_key_ipv6),
+ .maxLen = sizeof(struct ovs_key_ipv6),
+ .optional = TRUE},
+ [OVS_KEY_ATTR_TCP] = {.type = NL_A_UNSPEC,
+ .minLen = sizeof(struct ovs_key_tcp),
+ .maxLen = sizeof(struct ovs_key_tcp),
+ .optional = TRUE},
+ [OVS_KEY_ATTR_UDP] = {.type = NL_A_UNSPEC,
+ .minLen = sizeof(struct ovs_key_udp),
+ .maxLen = sizeof(struct ovs_key_udp),
+ .optional = TRUE},
+ [OVS_KEY_ATTR_ICMP] = {.type = NL_A_UNSPEC,
+ .minLen = sizeof(struct ovs_key_icmp),
+ .maxLen = sizeof(struct ovs_key_icmp),
+ .optional = TRUE},
+ [OVS_KEY_ATTR_ICMPV6] = {.type = NL_A_UNSPEC,
+ .minLen = sizeof(struct ovs_key_icmpv6),
+ .maxLen = sizeof(struct ovs_key_icmpv6),
+ .optional = TRUE},
+ [OVS_KEY_ATTR_ARP] = {.type = NL_A_UNSPEC,
+ .minLen = sizeof(struct ovs_key_arp),
+ .maxLen = sizeof(struct ovs_key_arp),
+ .optional = TRUE},
+ [OVS_KEY_ATTR_ND] = {.type = NL_A_UNSPEC,
+ .minLen = sizeof(struct ovs_key_nd),
+ .maxLen = sizeof(struct ovs_key_nd),
+ .optional = TRUE},
+ [OVS_KEY_ATTR_SKB_MARK] = {.type = NL_A_UNSPEC, .minLen = 4,
+ .maxLen = 4, .optional = TRUE},
+ [OVS_KEY_ATTR_TUNNEL] = {.type = NL_A_VAR_LEN, .optional = TRUE},
+ [OVS_KEY_ATTR_SCTP] = {.type = NL_A_UNSPEC,
+ .minLen = sizeof(struct ovs_key_sctp),
+ .maxLen = sizeof(struct ovs_key_sctp),
+ .optional = TRUE},
+ [OVS_KEY_ATTR_TCP_FLAGS] = {.type = NL_A_UNSPEC,
+ .minLen = 2, .maxLen = 2,
+ .optional = TRUE},
+ [OVS_KEY_ATTR_DP_HASH] = {.type = NL_A_UNSPEC, .minLen = 4,
+ .maxLen = 4, .optional = TRUE},
+ [OVS_KEY_ATTR_RECIRC_ID] = {.type = NL_A_UNSPEC, .minLen = 4,
+ .maxLen = 4, .optional = TRUE},
+ [OVS_KEY_ATTR_MPLS] = {.type = NL_A_VAR_LEN, .optional = TRUE}
+};
+
+/* For Parsing nested OVS_KEY_ATTR_TUNNEL attributes */
+static const NL_POLICY nlFlowTunnelKeyPolicy[] = {
+ [OVS_TUNNEL_KEY_ATTR_ID] = {.type = NL_A_UNSPEC, .minLen = 8,
+ .maxLen = 8, .optional = TRUE},
+ [OVS_TUNNEL_KEY_ATTR_IPV4_SRC] = {.type = NL_A_UNSPEC, .minLen = 4,
+ .maxLen = 4, .optional = TRUE},
+ [OVS_TUNNEL_KEY_ATTR_IPV4_DST] = {.type = NL_A_UNSPEC, .minLen = 4 ,
+ .maxLen = 4, .optional = FALSE},
+ [OVS_TUNNEL_KEY_ATTR_TOS] = {.type = NL_A_UNSPEC, .minLen = 1,
+ .maxLen = 1, .optional = TRUE},
+ [OVS_TUNNEL_KEY_ATTR_TTL] = {.type = NL_A_UNSPEC, .minLen = 1,
+ .maxLen = 1, .optional = TRUE},
+ [OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT] = {.type = NL_A_UNSPEC, .minLen = 0,
+ .maxLen = 0, .optional = TRUE},
+ [OVS_TUNNEL_KEY_ATTR_CSUM] = {.type = NL_A_UNSPEC, .minLen = 0,
+ .maxLen = 0, .optional = TRUE},
+ [OVS_TUNNEL_KEY_ATTR_OAM] = {.type = NL_A_UNSPEC, .minLen = 0,
+ .maxLen = 0, .optional = TRUE},
+ [OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS] = {.type = NL_A_VAR_LEN,
+ .optional = TRUE}
+};
+
+/* For Parsing nested OVS_FLOW_ATTR_ACTIONS attributes */
+static const NL_POLICY nlFlowActionPolicy[] = {
+ [OVS_ACTION_ATTR_OUTPUT] = {.type = NL_A_UNSPEC, .minLen = sizeof(UINT32),
+ .maxLen = sizeof(UINT32), .optional = TRUE},
+ [OVS_ACTION_ATTR_USERSPACE] = {.type = NL_A_VAR_LEN, .optional = TRUE},
+ [OVS_ACTION_ATTR_PUSH_VLAN] = {.type = NL_A_UNSPEC,
+ .minLen =
+ sizeof(struct ovs_action_push_vlan),
+ .maxLen =
+ sizeof(struct ovs_action_push_vlan),
+ .optional = TRUE},
+ [OVS_ACTION_ATTR_POP_VLAN] = {.type = NL_A_UNSPEC, .optional = TRUE},
+ [OVS_ACTION_ATTR_PUSH_MPLS] = {.type = NL_A_UNSPEC,
+ .minLen =
+ sizeof(struct ovs_action_push_mpls),
+ .maxLen =
+ sizeof(struct ovs_action_push_mpls),
+ .optional = TRUE},
+ [OVS_ACTION_ATTR_POP_MPLS] = {.type = NL_A_UNSPEC,
+ .minLen = sizeof(UINT16),
+ .maxLen = sizeof(UINT16),
+ .optional = TRUE},
+ [OVS_ACTION_ATTR_RECIRC] = {.type = NL_A_UNSPEC,
+ .minLen = sizeof(UINT32),
+ .maxLen = sizeof(UINT32),
+ .optional = TRUE},
+ [OVS_ACTION_ATTR_HASH] = {.type = NL_A_UNSPEC,
+ .minLen = sizeof(struct ovs_action_hash),
+ .maxLen = sizeof(struct ovs_action_hash),
+ .optional = TRUE},
+ [OVS_ACTION_ATTR_SET] = {.type = NL_A_VAR_LEN, .optional = TRUE},
+ [OVS_ACTION_ATTR_SAMPLE] = {.type = NL_A_VAR_LEN, .optional = TRUE}
+};
+
+/*
+ *----------------------------------------------------------------------------
+ * Netlink interface for flow commands.
+ *----------------------------------------------------------------------------
+ */
+NTSTATUS
+OvsFlowNlNewCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
+ UINT32 *replyLen)
+{
+ NTSTATUS rc = STATUS_SUCCESS;
+
+ UNREFERENCED_PARAMETER(usrParamsCtx);
+ UNREFERENCED_PARAMETER(replyLen);
+
+ return rc;
+}
+
/*
*----------------------------------------------------------------------------
* OvsDeleteFlowTable --
diff --git a/datapath-windows/ovsext/Flow.h b/datapath-windows/ovsext/Flow.h
index 3964c5464..602e56705 100644
--- a/datapath-windows/ovsext/Flow.h
+++ b/datapath-windows/ovsext/Flow.h
@@ -21,6 +21,7 @@
#include "Switch.h"
#include "User.h"
#include "NetProto.h"
+#include "Datapath.h"
typedef struct _OvsFlow {
LIST_ENTRY ListEntry; // In Datapath's flowTable.
@@ -70,6 +71,10 @@ NTSTATUS OvsGetFlowIoctl(PVOID inputBuffer, UINT32 inputLength,
UINT32 *replyLen);
NTSTATUS OvsFlushFlowIoctl(PVOID inputBuffer, UINT32 inputLength);
+NTSTATUS OvsFlowNlNewCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
+ UINT32 *replyLen);
+
+
/* Flags for tunneling */
#define OVS_TNL_F_DONT_FRAGMENT (1 << 0)
#define OVS_TNL_F_CSUM (1 << 1)