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 <ankursha...@vmware.com> To: dev@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-ankursha...@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@openvswitch.org http://openvswitch.org/mailman/listinfo/dev ------------------------------ End of dev Digest, Vol 62, Issue 318 ************************************ _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev