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

Saurabh Shah ssaurabh at vmware.com
Fri Aug 22 20:35:22 UTC 2014


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 <ankursharma at 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 <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:
>+ *
>+ *     
>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 at 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




More information about the dev mailing list