[ovs-dev] [PATCH 1/3 v2] datapath-windows: add netlink message parsing APIs

Ankur Sharma ankursharma at vmware.com
Fri Aug 22 16:59:59 UTC 2014


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 <ankursharma at vmware.com>
Reported-at: https://github.com/openvswitch/ovs-issues/issues/18
Acked-by: Nithin Raju <nithin at vmware.com>
Acked-by: Samuel Ghinet <sghinet at 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:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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




More information about the dev mailing list