Hey Ankur, Something to be careful of in future. You should wait for the reviewers to give an actual 'Acked-by' for a patch. If its a private Ack, it would be a good idea to mention it and then put an Ack for them. For example, Nithin & Samuel reviewed your V1 patch and gave comments, but that doesn't mean an implicit ack. Original reviewers or others may still have comments for the V1/V2 patch. I noticed this happen earlier as well, so before it becomes a common practice I thought I would call it out.
Thanks, Saurabh >In this change we introduce Netlink.c, Netlink.h and NetlinkProto.h >in datapath-windows. These files will provide netlink message >data structures and parsing APIs. > >Changes are on similar lines to userspace netlink code. > >We have mapped the userspace APIs and data structures to >kernel coding convention. >for example: >nlmsghdr ==> NL_MSG_HDR >nl_attr_get ==> NlAttrGet > >Signed-off-by: Ankur Sharma <ankursha...@vmware.com> >Reported-at: >https://urldefense.proofpoint.com/v1/url?u=https://github.com/openvswitch/ >ovs-issues/issues/18&k=oIvRg1%2BdGAgOoM1BIlLLqw%3D%3D%0A&r=pEkjsHfytvHEWuf >eZPpgqSOJMdMjuZPbesVsNhCUc0E%3D%0A&m=X4HSpcZAh0uja4JlI2B67trSce1pyzjScHTd8 >eVRg0E%3D%0A&s=3b03b9a3b3974fdcea3522e9234aec767761ce1a0bce97cf58c086c2d24 >44be2 >Acked-by: Nithin Raju <nit...@vmware.com> >Acked-by: Samuel Ghinet <sghi...@cloudbasesolutions.com> >--- > datapath-windows/ovsext/Netlink.c | 469 >+++++++++++++++++++++++++++++++++ > datapath-windows/ovsext/Netlink.h | 104 ++++++++ > datapath-windows/ovsext/NetlinkProto.h | 116 ++++++++ > datapath-windows/ovsext/OvsTypes.h | 9 + > 4 files changed, 698 insertions(+) > create mode 100644 datapath-windows/ovsext/Netlink.c > create mode 100644 datapath-windows/ovsext/Netlink.h > create mode 100644 datapath-windows/ovsext/NetlinkProto.h > >diff --git a/datapath-windows/ovsext/Netlink.c >b/datapath-windows/ovsext/Netlink.c >new file mode 100644 >index 0000000..1c8d054 >--- /dev/null >+++ b/datapath-windows/ovsext/Netlink.c >@@ -0,0 +1,469 @@ >+/* >+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. >+ * >+ * Licensed under the Apache License, Version 2.0 (the "License"); >+ * you may not use this file except in compliance with the License. >+ * You may obtain a copy of the License at: >+ * >+ * >https://urldefense.proofpoint.com/v1/url?u=http://www.apache.org/licenses/ >LICENSE-2.0&k=oIvRg1%2BdGAgOoM1BIlLLqw%3D%3D%0A&r=pEkjsHfytvHEWufeZPpgqSOJ >MdMjuZPbesVsNhCUc0E%3D%0A&m=X4HSpcZAh0uja4JlI2B67trSce1pyzjScHTd8eVRg0E%3D >%0A&s=34bffd0bd09ab4fe0fc21859b998e4323e8a5ac1dea3f628e32ec8c1e12aa6a6 >+ * >+ * Unless required by applicable law or agreed to in writing, software >+ * distributed under the License is distributed on an "AS IS" BASIS, >+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or >implied. >+ * See the License for the specific language governing permissions and >+ * limitations under the License. >+ */ >+ >+#include "precomp.h" >+#include "NetlinkProto.h" >+#include "Netlink.h" >+ >+#ifdef OVS_DBG_MOD >+#undef OVS_DBG_MOD >+#endif >+#define OVS_DBG_MOD OVS_DBG_NETLINK >+#include "OvsDebug.h" >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Netlink message accessing the payload. >+ * >-------------------------------------------------------------------------- >- >+ */ >+PVOID >+NlMsgAt(const PNL_MSG_HDR nlh, UINT32 offset) >+{ >+ return ((PCHAR)nlh + offset); >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Returns the size of netlink message. >+ * >-------------------------------------------------------------------------- >- >+ */ >+UINT32 >+NlMsgSize(const PNL_MSG_HDR nlh) >+{ >+ return nlh->nlmsgLen; >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Returns pointer to nlmsg payload. >+ * >-------------------------------------------------------------------------- >- >+ */ >+PCHAR >+NlMsgPayload(const PNL_MSG_HDR nlh) >+{ >+ return ((PCHAR)nlh + NLMSG_HDRLEN); >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Returns length of nlmsg payload. >+ * >-------------------------------------------------------------------------- >- >+ */ >+UINT32 >+NlMsgPayloadLen(const PNL_MSG_HDR nlh) >+{ >+ return nlh->nlmsgLen - NLMSG_HDRLEN; >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Returns pointer to nlmsg attributes. >+ * >-------------------------------------------------------------------------- >- >+ */ >+PNL_ATTR >+NlMsgAttrs(const PNL_MSG_HDR nlh) >+{ >+ return (PNL_ATTR) (NlMsgPayload(nlh) + GENL_HDRLEN + OVS_HDRLEN); >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Returns size of to nlmsg attributes. >+ * >-------------------------------------------------------------------------- >- >+ */ >+INT >+NlMsgAttrLen(const PNL_MSG_HDR nlh) >+{ >+ return NlMsgPayloadLen(nlh) - GENL_HDRLEN - OVS_HDRLEN; >+} >+ >+/* Netlink message parse. */ >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Returns next netlink message in the stream. >+ * >-------------------------------------------------------------------------- >- >+ */ >+PNL_MSG_HDR >+NlMsgNext(const PNL_MSG_HDR nlh) >+{ >+ return (PNL_MSG_HDR)((PCHAR)nlh + >+ NLMSG_ALIGN(nlh->nlmsgLen)); >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Netlink Attr helper APIs. >+ * >-------------------------------------------------------------------------- >- >+ */ >+INT >+NlAttrIsValid(const PNL_ATTR nla, UINT32 maxlen) >+{ >+ return (maxlen >= sizeof *nla >+ && nla->nlaLen >= sizeof *nla >+ && nla->nlaLen <= maxlen); >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Returns alligned length of the attribute. >+ * >-------------------------------------------------------------------------- >- >+ */ >+UINT32 >+NlAttrLenPad(const PNL_ATTR nla, UINT32 maxlen) >+{ >+ UINT32 len = NLA_ALIGN(nla->nlaLen); >+ >+ return len <= maxlen ? len : nla->nlaLen; >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Default minimum payload size for each type of attribute. >+ * >-------------------------------------------------------------------------- >- >+ */ >+UINT32 >+NlAttrMinLen(NL_ATTR_TYPE type) >+{ >+ switch (type) { >+ case NL_A_NO_ATTR: return 0; >+ case NL_A_UNSPEC: return 0; >+ case NL_A_U8: return 1; >+ case NL_A_U16: return 2; >+ case NL_A_U32: return 4; >+ case NL_A_U64: return 8; >+ case NL_A_STRING: return 1; >+ case NL_A_FLAG: return 0; >+ case NL_A_NESTED: return 0; >+ case N_NL_ATTR_TYPES: >+ default: >+ OVS_LOG_WARN("Unsupprted attribute type: %d", type); >+ ASSERT(0); >+ } >+ >+ /* To keep compiler happy */ >+ return 0; >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Default maximum payload size for each type of attribute. >+ * >-------------------------------------------------------------------------- >- >+ */ >+UINT32 >+NlAttrMaxLen(NL_ATTR_TYPE type) >+{ >+ switch (type) { >+ case NL_A_NO_ATTR: return SIZE_MAX; >+ case NL_A_UNSPEC: return SIZE_MAX; >+ case NL_A_U8: return 1; >+ case NL_A_U16: return 2; >+ case NL_A_U32: return 4; >+ case NL_A_U64: return 8; >+ case NL_A_STRING: return SIZE_MAX; >+ case NL_A_FLAG: return SIZE_MAX; >+ case NL_A_NESTED: return SIZE_MAX; >+ case N_NL_ATTR_TYPES: >+ default: >+ OVS_LOG_WARN("Unsupprted attribute type: %d", type); >+ ASSERT(0); >+ } >+ >+ /* To keep compiler happy */ >+ return 0; >+} >+ >+/* Netlink attribute iteration. */ >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Returns the next attribute. >+ * >-------------------------------------------------------------------------- >- >+ */ >+PNL_ATTR >+NlAttrNext(const PNL_ATTR nla) >+{ >+ return (PNL_ATTR)((UINT8 *)nla + NLA_ALIGN(nla->nlaLen)); >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >+ * Returns the bits of 'nla->nlaType' that are significant for >determining >+ * its type. >+ * >-------------------------------------------------------------------------- >+ */ >+UINT16 >+NlAttrType(const PNL_ATTR nla) >+{ >+ return nla->nlaType & NLA_TYPE_MASK; >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >+ * Returns the netlink attribute data. >+ * >-------------------------------------------------------------------------- >+ */ >+PVOID >+NlAttrData(const PNL_ATTR nla) >+{ >+ return ((PCHAR)nla + NLA_HDRLEN); >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Returns the number of bytes in the payload of attribute 'nla'. >+ * >-------------------------------------------------------------------------- >- >+ */ >+UINT32 >+NlAttrGetSize(const PNL_ATTR nla) >+{ >+ return nla->nlaLen - NLA_HDRLEN; >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Returns the first byte in the payload of attribute 'nla'. >+ * >-------------------------------------------------------------------------- >- >+ */ >+const PVOID >+NlAttrGet(const PNL_ATTR nla) >+{ >+ ASSERT(nla->nlaLen >= NLA_HDRLEN); >+ return nla + 1; >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Asserts that 'nla''s payload is at least 'size' bytes long, and >returns the >+ * first byte of the payload. >+ * >-------------------------------------------------------------------------- >- >+ */ >+const >+PVOID NlAttrGetUnspec(const PNL_ATTR nla, UINT32 size) >+{ >+ UNREFERENCED_PARAMETER(size); >+ ASSERT(nla->nlaLen >= NLA_HDRLEN + size); >+ return nla + 1; >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Returns the 64-bit network byte order value in 'nla''s payload. >+ * >+ * Asserts that 'nla''s payload is at least 8 bytes long. >+ * >-------------------------------------------------------------------------- >- >+ */ >+BE64 >+NlAttrGetBe64(const PNL_ATTR nla) >+{ >+ return NL_ATTR_GET_AS(nla, BE64); >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Returns the 32-bit network byte order value in 'nla''s payload. >+ * >+ * Asserts that 'nla''s payload is at least 4 bytes long. >+ * >-------------------------------------------------------------------------- >- >+ */ >+BE32 >+NlAttrGetBe32(const PNL_ATTR nla) >+{ >+ return NL_ATTR_GET_AS(nla, BE32); >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Returns the 8-bit value in 'nla''s payload. >+ * >-------------------------------------------------------------------------- >- >+ */ >+UINT8 >+NlAttrGetU8(const PNL_ATTR nla) >+{ >+ return NL_ATTR_GET_AS(nla, UINT8); >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Returns the 32-bit host byte order value in 'nla''s payload. >+ * Asserts that 'nla''s payload is at least 4 bytes long. >+ * >-------------------------------------------------------------------------- >- >+ */ >+UINT32 >+NlAttrGetU32(const PNL_ATTR nla) >+{ >+ return NL_ATTR_GET_AS(nla, UINT32); >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Validate the netlink attribute against the policy >+ * >-------------------------------------------------------------------------- >- >+ */ >+BOOLEAN >+NlAttrValidate(const PNL_ATTR nla, const PNL_POLICY policy) >+{ >+ UINT32 minLen; >+ UINT32 maxLen; >+ UINT32 len; >+ BOOLEAN ret = FALSE; >+ >+ if (policy->type == NL_A_NO_ATTR) { >+ ret = TRUE; >+ goto done; >+ } >+ >+ /* Figure out min and max length. */ >+ minLen = policy->minLen; >+ if (!minLen) { >+ minLen = NlAttrMinLen(policy->type); >+ } >+ maxLen = policy->maxLen; >+ if (!maxLen) { >+ maxLen = NlAttrMaxLen(policy->type); >+ } >+ >+ /* Verify length. */ >+ len = NlAttrGetSize(nla); >+ if (len < minLen || len > maxLen) { >+ OVS_LOG_WARN("Attribute: %p, len: %d, not in valid range, " >+ "min: %d, max: %d", nla, len, minLen, maxLen); >+ goto done; >+ } >+ >+ /* Strings must be null terminated and must not have embedded nulls. >*/ >+ if (policy->type == NL_A_STRING) { >+ if (((PCHAR) nla)[nla->nlaLen - 1]) { >+ OVS_LOG_WARN("Attributes %p lacks null at the end", nla); >+ goto done; >+ } >+ >+ if (memchr(nla + 1, '\0', len - 1) != NULL) { >+ OVS_LOG_WARN("Attributes %p has bad length", nla); >+ goto done; >+ } >+ } >+ >+done: >+ return ret; >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Returns an attribute of type 'type' from a series of >+ * attributes. >+ * >-------------------------------------------------------------------------- >- >+ */ >+const PNL_ATTR >+NlAttrFind__(const PNL_ATTR attrs, UINT32 size, UINT16 type) >+{ >+ PNL_ATTR iter = NULL; >+ PNL_ATTR ret = NULL; >+ UINT32 left; >+ >+ NL_ATTR_FOR_EACH (iter, left, attrs, size) { >+ if (NlAttrType(iter) == type) { >+ ret = iter; >+ goto done; >+ } >+ } >+ >+done: >+ return ret; >+} >+ >+/* >+ * >-------------------------------------------------------------------------- >- >+ * Returns the first Netlink attribute within 'nla' with the specified >+ * 'type'. >+ * >+ * This function does not validate the attribute's length. >+ * >-------------------------------------------------------------------------- >- >+ */ >+const PNL_ATTR >+NlAttrFindNested(const PNL_ATTR nla, UINT16 type) >+{ >+ return NlAttrFind__((const PNL_ATTR)(NlAttrGet(nla)), >+ NlAttrGetSize(nla), type); >+} >+ >+/* >+ >*------------------------------------------------------------------------- >--- >+ * Parses the netlink message at a given offset (attrOffset) >+ * as a series of attributes. A pointer to the attribute with type >+ * 'type' is stored in attrs at index 'type'. policy is used to define >the >+ * attribute type validation parameters. >+ * 'nla_offset' should be NLMSG_HDRLEN + GENL_HDRLEN + OVS_HEADER >+ * >+ * Returns NDIS_STATUS_SUCCESS normally. Fails only if packet data >cannot be accessed >+ * (e.g. if Pkt_CopyBytesOut() returns an error). >+ >*------------------------------------------------------------------------- >--- >+ */ >+BOOLEAN NlAttrParse(const PNL_MSG_HDR nlMsg, UINT32 attrOffset, >+ const NL_POLICY policy[], >+ PNL_ATTR attrs[], UINT32 n_attrs) >+{ >+ PNL_ATTR nla; >+ UINT32 left; >+ UINT32 iter; >+ BOOLEAN ret = FALSE; >+ >+ memset(attrs, 0, n_attrs * sizeof *attrs); >+ >+ if ((NlMsgSize(nlMsg) < attrOffset) || (!(NlMsgAttrLen(nlMsg)))) { >+ OVS_LOG_WARN("No attributes in nlMsg: %p at offset: %d", >+ nlMsg, attrOffset); >+ goto done; >+ } >+ >+ NL_ATTR_FOR_EACH (nla, left, NlMsgAt(nlMsg, attrOffset), >+ NlMsgSize(nlMsg) - attrOffset) >+ { >+ UINT16 type = NlAttrType(nla); >+ if (type < n_attrs && policy[type].type != NL_A_NO_ATTR) { >+ /* Typecasting to keep the compiler happy */ >+ const PNL_POLICY e = (const PNL_POLICY)(&policy[type]); >+ if (!NlAttrValidate(nla, e)) { >+ goto done; >+ } >+ >+ if (attrs[type]) { >+ OVS_LOG_WARN("Duplicate attribute in nlMsg: %p, " >+ "type: %u", nlMsg, type); >+ } >+ >+ attrs[type] = nla; >+ } >+ } >+ >+ if (left) { >+ OVS_LOG_ERROR("Attributes followed by garbage"); >+ goto done; >+ } >+ >+ for (iter = 0; iter < n_attrs; iter++) { >+ const PNL_POLICY e = (const PNL_POLICY)(&policy[iter]); >+ if (e->type != NL_A_NO_ATTR && !attrs[iter]) { >+ OVS_LOG_ERROR("Required attr:%d missing", iter); >+ goto done; >+ } >+ } >+ >+ ret = TRUE; >+ >+done: >+ return ret; >+} >diff --git a/datapath-windows/ovsext/Netlink.h >b/datapath-windows/ovsext/Netlink.h >new file mode 100644 >index 0000000..bc89666 >--- /dev/null >+++ b/datapath-windows/ovsext/Netlink.h >@@ -0,0 +1,104 @@ >+/* >+ * Copyright (c) 2008, 2009, 2010, 2011, 2013, 2014 Nicira, Inc. >+ * >+ * Licensed under the Apache License, Version 2.0 (the "License"); >+ * you may not use this file except in compliance with the License. >+ * You may obtain a copy of the License at: >+ * >+ * >https://urldefense.proofpoint.com/v1/url?u=http://www.apache.org/licenses/ >LICENSE-2.0&k=oIvRg1%2BdGAgOoM1BIlLLqw%3D%3D%0A&r=pEkjsHfytvHEWufeZPpgqSOJ >MdMjuZPbesVsNhCUc0E%3D%0A&m=X4HSpcZAh0uja4JlI2B67trSce1pyzjScHTd8eVRg0E%3D >%0A&s=34bffd0bd09ab4fe0fc21859b998e4323e8a5ac1dea3f628e32ec8c1e12aa6a6 >+ * >+ * Unless required by applicable law or agreed to in writing, software >+ * distributed under the License is distributed on an "AS IS" BASIS, >+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or >implied. >+ * See the License for the specific language governing permissions and >+ * limitations under the License. >+ */ >+ >+#ifndef __NETLINK_H_ >+#define __NETLINK_H_ 1 >+ >+#include "OvsTypes.h" >+#include "NetlinkProto.h" >+ >+/* Netlink attribute types. */ >+typedef enum >+{ >+ NL_A_NO_ATTR = 0, >+ NL_A_UNSPEC, >+ NL_A_U8, >+ NL_A_U16, >+ NL_A_BE16 = NL_A_U16, >+ NL_A_U32, >+ NL_A_BE32 = NL_A_U32, >+ NL_A_U64, >+ NL_A_BE64 = NL_A_U64, >+ NL_A_STRING, >+ NL_A_FLAG, >+ NL_A_NESTED, >+ N_NL_ATTR_TYPES >+} NL_ATTR_TYPE; >+ >+/* Netlink attribute policy. >+ * Specifies the policy for parsing for netlink attribute. */ >+typedef struct _NL_POLICY >+{ >+ NL_ATTR_TYPE type; >+ UINT32 minLen; >+ UINT32 maxLen; >+} NL_POLICY, *PNL_POLICY; >+ >+/* This macro is careful to check for attributes with bad lengths. */ >+#define NL_ATTR_FOR_EACH(ITER, LEFT, ATTRS, ATTRS_LEN) \ >+ for ((ITER) = (ATTRS), (LEFT) = (ATTRS_LEN); \ >+ NlAttrIsValid(ITER, LEFT); \ >+ (LEFT) -= NlAttrLenPad(ITER, LEFT), (ITER) = NlAttrNext(ITER)) >+ >+/* This macro does not check for attributes with bad lengths. It should >only >+ * be used with messages from trusted sources or with messages that have >+ * already been validated (e.g. with NL_ATTR_FOR_EACH). */ >+#define NL_ATTR_FOR_EACH_UNSAFE(ITER, LEFT, ATTRS, ATTRS_LEN) \ >+ for ((ITER) = (ATTRS), (LEFT) = (ATTRS_LEN); \ >+ (LEFT) > 0; \ >+ (LEFT) -= NLA_ALIGN((ITER)->nlaLen), (ITER) = NlAttrNext(ITER)) >+ >+#define NL_ATTR_GET_AS(NLA, TYPE) \ >+ (*(TYPE*) NlAttrGetUnspec(nla, sizeof(TYPE))) >+ >+/* Netlink message accessing the payload */ >+PVOID NlMsgAt(const PNL_MSG_HDR nlh, UINT32 offset); >+UINT32 NlMsgSize(const PNL_MSG_HDR nlh); >+PCHAR NlMsgPayload(const PNL_MSG_HDR nlh); >+UINT32 NlMsgPayloadLen(const PNL_MSG_HDR nlh); >+PNL_ATTR NlMsgAttrs(const PNL_MSG_HDR nlh); >+INT NlMsgAttrLen(const PNL_MSG_HDR nlh); >+ >+/* Netlink message parse */ >+PNL_MSG_HDR NlMsgNext(const PNL_MSG_HDR nlh); >+INT NlAttrIsValid(const PNL_ATTR nla, UINT32 maxlen); >+UINT32 NlAttrLenPad(const PNL_ATTR nla, UINT32 maxlen); >+ >+/* Netlink attribute parsing. */ >+UINT32 NlAttrMinLen(NL_ATTR_TYPE type); >+UINT32 NlAttrMinLen(NL_ATTR_TYPE type); >+PNL_ATTR NlAttrNext(const PNL_ATTR nla); >+UINT16 NlAttrType(const PNL_ATTR nla); >+PVOID NlAttrData(const PNL_ATTR nla); >+UINT32 NlAttrGetSize(const PNL_ATTR nla); >+const PVOID NlAttrGet(const PNL_ATTR nla); >+const PVOID NlAttrGetUnspec(const PNL_ATTR nla, UINT32 size); >+BE64 NlAttrGetBe64(const PNL_ATTR nla); >+BE32 NlAttrGetBe32(const PNL_ATTR nla); >+UINT8 NlAttrGetU8(const PNL_ATTR nla); >+UINT32 NlAttrGetU32(const PNL_ATTR nla); >+const PNL_ATTR NlAttrFind__(const PNL_ATTR attrs, >+ UINT32 size, UINT16 type); >+const PNL_ATTR NlAttrFindNested(const PNL_ATTR nla, >+ UINT16 type); >+BOOLEAN NlAttrParse(const PNL_MSG_HDR nlMsg, UINT32 attrOffset, >+ const NL_POLICY policy[], >+ PNL_ATTR attrs[], UINT32 n_attrs); >+ >+/* Netlink attribute validation */ >+BOOLEAN NlAttrValidate(const PNL_ATTR, const PNL_POLICY); >+ >+#endif /* __NETLINK_H_ */ >diff --git a/datapath-windows/ovsext/NetlinkProto.h >b/datapath-windows/ovsext/NetlinkProto.h >new file mode 100644 >index 0000000..20ab750 >--- /dev/null >+++ b/datapath-windows/ovsext/NetlinkProto.h >@@ -0,0 +1,116 @@ >+/* >+ * Copyright (c) 2008, 2010, 2011, 2014 Nicira, Inc. >+ * >+ * Licensed under the Apache License, Version 2.0 (the "License"); >+ * you may not use this file except in compliance with the License. >+ * You may obtain a copy of the License at: >+ * >+ * >https://urldefense.proofpoint.com/v1/url?u=http://www.apache.org/licenses/ >LICENSE-2.0&k=oIvRg1%2BdGAgOoM1BIlLLqw%3D%3D%0A&r=pEkjsHfytvHEWufeZPpgqSOJ >MdMjuZPbesVsNhCUc0E%3D%0A&m=X4HSpcZAh0uja4JlI2B67trSce1pyzjScHTd8eVRg0E%3D >%0A&s=34bffd0bd09ab4fe0fc21859b998e4323e8a5ac1dea3f628e32ec8c1e12aa6a6 >+ * >+ * Unless required by applicable law or agreed to in writing, software >+ * distributed under the License is distributed on an "AS IS" BASIS, >+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or >implied. >+ * See the License for the specific language governing permissions and >+ * limitations under the License. >+ */ >+ >+#ifndef __NETLINK_PROTO_H_ >+#define __NETLINK_PROTO_H_ 1 >+ >+/* Netlink protocol definitions. >+ * >+ * Netlink is a message framing format described in RFC 3549 and used >heavily >+ * in Linux to access the network stack. Open vSwitch uses AF_NETLINK >sockets >+ * for this purpose on Linux. On Windows platform too, Open vSwitch uses >+ * netlink message format for userspace-kernelspace communication. >+ * >+ * This header provides access to the Netlink message framing definitions >+ * regardless of platform. >+ */ >+#include "OvsTypes.h" >+ >+#define BUILD_ASSERT(EXPR) \ >+ typedef char AssertOnCompileFailed[(EXPR) ? 1: -1] >+#define BUILD_ASSERT_DECL(EXPR) BUILD_ASSERT(EXPR) >+ >+/* Returns X / Y, rounding up. X must be nonnegative to round >correctly. */ >+#define DIV_ROUND_UP(X, Y) (((X) + ((Y) - 1)) / (Y)) >+ >+/* Returns X rounded up to the nearest multiple of Y. */ >+#define ROUND_UP(X, Y) (DIV_ROUND_UP(X, Y) * (Y)) >+ >+/* Netlink message */ >+ >+/* nlmsg_flags bits. */ >+#define NLM_F_REQUEST 0x001 >+#define NLM_F_MULTI 0x002 >+#define NLM_F_ACK 0x004 >+#define NLM_F_ECHO 0x008 >+ >+#define NLM_F_ROOT 0x100 >+#define NLM_F_MATCH 0x200 >+#define NLM_F_EXCL 0x200 >+#define NLM_F_ATOMIC 0x400 >+#define NLM_F_CREATE 0x400 >+#define NLM_F_DUMP (NLM_F_ROOT | NLM_F_MATCH) >+ >+/* nlmsg_type values. */ >+#define NLMSG_NOOP 1 >+#define NLMSG_ERROR 2 >+#define NLMSG_DONE 3 >+#define NLMSG_OVERRUN 4 >+ >+#define NLMSG_MIN_TYPE 0x10 >+ >+#define MAX_LINKS 32 >+ >+#define NLMSG_ALIGNTO 4 >+#define NLMSG_ALIGN(SIZE) ROUND_UP(SIZE, NLMSG_ALIGNTO) >+ >+#define NLA_ALIGNTO 4 >+#define NLA_ALIGN(SIZE) ROUND_UP(SIZE, NLA_ALIGNTO) >+ >+typedef struct ovs_header OVS_HDR, *POVS_HDR; >+ >+typedef struct _NL_MSG_HDR { >+ UINT32 nlmsgLen; >+ UINT16 nlmsgType; >+ UINT16 nlmsgFlags; >+ UINT32 nlmsgSeq; >+ UINT32 nlmsgPid; >+} NL_MSG_HDR, *PNL_MSG_HDR; >+BUILD_ASSERT_DECL(sizeof(NL_MSG_HDR) == 16); >+ >+typedef struct _NlMsgErr >+{ >+ INT error; >+ NL_MSG_HDR msg; >+} NL_MSG_ERR, *PNL_MSG_ERR; >+BUILD_ASSERT_DECL(sizeof(NL_MSG_ERR) == 20); >+ >+typedef struct _GENL_MSG_HDR { >+ UINT8 cmd; >+ UINT8 version; >+ UINT16 reserved; >+} GENL_MSG_HDR, *PGENL_MDG_HDR; >+BUILD_ASSERT_DECL(sizeof(GENL_MSG_HDR) == 4); >+ >+/* Netlink attributes */ >+typedef struct _NL_ATTR { >+ UINT16 nlaLen; >+ UINT16 nlaType; >+} NL_ATTR, *PNL_ATTR; >+BUILD_ASSERT_DECL(sizeof(NL_ATTR) == 4); >+ >+#ifndef NLA_TYPE_MASK >+#define NLA_F_NESTED (1 << 15) >+#define NLA_F_NET_BYTEORDER (1 << 14) >+#define NLA_TYPE_MASK ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER) >+#endif >+ >+#define NLMSG_HDRLEN ((INT) NLMSG_ALIGN(sizeof(NL_MSG_HDR))) >+#define GENL_HDRLEN NLMSG_ALIGN(sizeof(GENL_MSG_HDR)) >+#define OVS_HDRLEN NLMSG_ALIGN(sizeof(OVS_HDR)) >+#define NLA_HDRLEN ((INT) NLA_ALIGN(sizeof(NL_ATTR))) >+ >+#endif /* NetlinProto.h */ >diff --git a/datapath-windows/ovsext/OvsTypes.h >b/datapath-windows/ovsext/OvsTypes.h >index 402c39f..57b27e7 100644 >--- a/datapath-windows/ovsext/OvsTypes.h >+++ b/datapath-windows/ovsext/OvsTypes.h >@@ -17,6 +17,8 @@ > #ifndef __OVS_TYPES_H_ > #define __OVS_TYPES_H_ 1 > >+/* Defines the userspace specific data types >+ * for files included from user space. */ > typedef unsigned long long uint64, uint64_t, ovs_be64, u64; > typedef long long int64, int64_t; > typedef unsigned int uint32, uint32_t, ovs_be32, u32; >@@ -27,6 +29,13 @@ typedef uint32 __u32, __be32; > typedef uint16 __u16, __be16; > typedef uint8 __u8; > >+/* Defines the userspace specific data types for file >+ * included within kernel only. */ >+typedef UINT32 BE32; >+typedef UINT64 BE64; >+ > #define ETH_ALEN 6 > >+#define SIZE_MAX MAXUINT32 >+ > #endif /* __OVS_TYPES_H_ */ >-- >1.9.1 > >_______________________________________________ >dev mailing list >dev@openvswitch.org >https://urldefense.proofpoint.com/v1/url?u=http://openvswitch.org/mailman/ >listinfo/dev&k=oIvRg1%2BdGAgOoM1BIlLLqw%3D%3D%0A&r=pEkjsHfytvHEWufeZPpgqSO >JMdMjuZPbesVsNhCUc0E%3D%0A&m=X4HSpcZAh0uja4JlI2B67trSce1pyzjScHTd8eVRg0E%3 >D%0A&s=7b7db0d2a61da6c15a40f8d4523e334e4942b1aac1144d6ef74b45ffb5cc5528 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev