[ovs-dev] [PATCH v1 06/10] datapath-windows/Flow.c : Basic support for add-flow.

Samuel Ghinet sghinet at cloudbasesolutions.com
Thu Sep 25 15:44:30 UTC 2014


Hey Ankur,

A few notes:
> +NETLINK_CMD nlFlowFamilyCmdOps[] = {
> +    { .cmd              = OVS_FLOW_CMD_NEW,
> +      .handler          = OvsFlowNlNewCmdHandler,
> +      .supportedDevOp   = OVS_TRANSACTION_DEV_OP,
> +      .validateDpIndex  = FALSE
> +    }
> +};

It is possible that we need to have validateDpIndex  = TRUE here.

Regarding the policies, several "optionals" for them are wrong, or perhaps depending on context:
> +    [OVS_FLOW_ATTR_KEY] = {.type = NL_A_NESTED, .optional = TRUE},
For Flow New, Set, Get, the KEY is always required.
For Flow Delete, if KEY is not provided it means "delete all". Dump does not require it.

> +    [OVS_KEY_ATTR_IN_PORT] = {.type = NL_A_UNSPEC, .minLen = 4,
> +                              .maxLen = 4, .optional = TRUE},
I believe the input port is always required: all flows must have an input port non-masked, as I remember.
The same goes for ethernet type.
If we have a flow/key/tunnel, tunnel destination ipv4 address is required (non-masked).

Perhaps it would be best if you set the option values depending on context.

Regards,
Sam

________________________________________
Date: Wed, 24 Sep 2014 00:15:40 -0700
From: Ankur Sharma <ankursharma at vmware.com>
To: dev at openvswitch.org
Subject: [ovs-dev] [PATCH v1 06/10] datapath-windows/Flow.c : Basic
        support for add-flow.
Message-ID: <1411542944-19374-6-git-send-email-ankursharma at vmware.com>

This patch covers basic changes in registering add flow handler.
And declaring FLOW related attribute parsing policies.
---
 datapath-windows/ovsext/Datapath.c |  18 ++++-
 datapath-windows/ovsext/Flow.c     | 152 +++++++++++++++++++++++++++++++++++++
 datapath-windows/ovsext/Flow.h     |   5 ++
 3 files changed, 171 insertions(+), 4 deletions(-)

diff --git a/datapath-windows/ovsext/Datapath.c b/datapath-windows/ovsext/Datapath.c
index ffb7d44..7b064f9 100644
--- a/datapath-windows/ovsext/Datapath.c
+++ b/datapath-windows/ovsext/Datapath.c
@@ -191,14 +191,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  = FALSE
+    }
+};
+
 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,
@@ -689,8 +697,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:
     case OVS_WIN_NL_VPORT_FAMILY_ID:
         status = STATUS_NOT_IMPLEMENTED;
         goto done;
diff --git a/datapath-windows/ovsext/Flow.c b/datapath-windows/ovsext/Flow.c
index dae1dca..25b39c1 100644
--- a/datapath-windows/ovsext/Flow.c
+++ b/datapath-windows/ovsext/Flow.c
@@ -51,6 +51,158 @@ 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 = TRUE},
+    [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 */
+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 = TRUE},
+    [OVS_KEY_ATTR_ETHERNET] = {.type = NL_A_UNSPEC,
+                               .minLen = sizeof(struct ovs_key_ethernet),
+                               .maxLen = sizeof(struct ovs_key_ethernet),
+                               .optional = TRUE},
+    [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 = TRUE},
+    [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 3964c54..602e567 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)
--
1.9.1



------------------------------

Subject: Digest Footer

_______________________________________________
dev mailing list
dev at openvswitch.org
http://openvswitch.org/mailman/listinfo/dev


------------------------------

End of dev Digest, Vol 62, Issue 318
************************************



More information about the dev mailing list