[ovs-dev] [PATCH v3 2/2] datapath-windows/Netlink: Nested attributes put/parse.

Ankur Sharma ankursharma at vmware.com
Thu Sep 11 00:30:34 UTC 2014


Added APIs for creating and parsing nested netlink attributes.
APIs are on similar lines as userspace netlink code.

Signed-off-by: Ankur Sharma <ankursharma at vmware.com>
Acked-by: Samuel Ghinet <sghinet at cloudbasesolutions.com>
Acked-by: Nithin Raju <nithin at vmware.com>
---
 datapath-windows/ovsext/Netlink/Netlink.c | 92 ++++++++++++++++++++++++++++++-
 datapath-windows/ovsext/Netlink/Netlink.h | 12 ++++
 2 files changed, 101 insertions(+), 3 deletions(-)

diff --git a/datapath-windows/ovsext/Netlink/Netlink.c b/datapath-windows/ovsext/Netlink/Netlink.c
index 99cdc0e..5faf07f 100644
--- a/datapath-windows/ovsext/Netlink/Netlink.c
+++ b/datapath-windows/ovsext/Netlink/Netlink.c
@@ -418,6 +418,73 @@ NlMsgPutHeadString(PNL_BUFFER buf, UINT16 type, PCHAR value)
                                (UINT16)strLen));
 }
 
+/*
+ * ---------------------------------------------------------------------------
+ * Adds the header for nested netlink attributes. It
+ * returns the offset of this header. If addition of header fails
+ * then returned value of offset will be zero.
+ * Refer nl_msg_start_nested for more details.
+ * ---------------------------------------------------------------------------
+ */
+UINT32
+NlMsgStartNested(PNL_BUFFER buf, UINT16 type)
+{
+    UINT32 offset = NlBufSize(buf);
+    PCHAR nlaData = NULL;
+
+    nlaData = NlMsgPutTailUnspecUninit(buf, type, 0);
+
+    if (!nlaData) {
+        /* Value zero must be reated as error by the caller.
+         * This is because an attribute can never be added
+         * at offset zero, it will always come after NL_MSG_HDR,
+         * GENL_HDR and OVS_HEADER. */
+        offset = 0;
+    }
+
+    return offset;
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * Finalizes the nested netlink attribute by updating the nla_len.
+ * offset should be the one returned by NlMsgStartNested.
+ * Refer nl_msg_end_nested for more details.
+ * ---------------------------------------------------------------------------
+ */
+VOID
+NlMsgEndNested(PNL_BUFFER buf, UINT32 offset)
+{
+    PNL_ATTR attr = (PNL_ATTR)(NlBufAt(buf, offset, sizeof *attr));
+
+    /* Typecast to keep compiler happy.
+     * Attribute length would never exceed MAX UINT16.*/
+    attr->nlaLen = (UINT16)(NlBufSize(buf) - offset);
+}
+
+/*
+ * --------------------------------------------------------------------------
+ * Appends a nested Netlink attribute of the given 'type', with the 'size'
+ * bytes of content starting at 'data', to 'msg'.
+ * Refer nl_msg_put_nested for more details.
+ * --------------------------------------------------------------------------
+ */
+VOID
+NlMsgPutNested(PNL_BUFFER buf, UINT16 type,
+               const PVOID data, UINT32 size)
+{
+    UINT32 offset = NlMsgStartNested(buf, type);
+    BOOLEAN ret = FALSE;
+
+    ASSERT(offset);
+
+    ret = NlMsgPutTail(buf, data, size);
+
+    ASSERT(ret);
+
+    NlMsgEndNested(buf, offset);
+}
+
 /* Accessing netlink message payload */
 
 /*
@@ -807,9 +874,10 @@ NlAttrFindNested(const PNL_ATTR nla, UINT16 type)
  * Returns BOOLEAN to indicate success/failure.
  *----------------------------------------------------------------------------
  */
-BOOLEAN NlAttrParse(const PNL_MSG_HDR nlMsg, UINT32 attrOffset,
-                    const NL_POLICY policy[],
-                    PNL_ATTR attrs[], UINT32 n_attrs)
+BOOLEAN
+NlAttrParse(const PNL_MSG_HDR nlMsg, UINT32 attrOffset,
+            const NL_POLICY policy[],
+            PNL_ATTR attrs[], UINT32 n_attrs)
 {
     PNL_ATTR nla;
     UINT32 left;
@@ -862,3 +930,21 @@ BOOLEAN NlAttrParse(const PNL_MSG_HDR nlMsg, UINT32 attrOffset,
 done:
     return ret;
 }
+
+/*
+ *----------------------------------------------------------------------------
+ * Parses the netlink message for nested attributes. attrOffset must be the
+ * offset of nla which is the header of the nested attribute series.
+ * Refer nl_parse_nested for more details.
+ *
+ * Returns BOOLEAN to indicate success/failure.
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN
+NlAttrParseNested(const PNL_MSG_HDR nlMsg, UINT32 attrOffset,
+                  const NL_POLICY policy[],
+                  PNL_ATTR attrs[], UINT32 n_attrs)
+{
+    return NlAttrParse(nlMsg, attrOffset + NLA_HDRLEN,
+                       policy, attrs, n_attrs);
+}
diff --git a/datapath-windows/ovsext/Netlink/Netlink.h b/datapath-windows/ovsext/Netlink/Netlink.h
index 7ca67d7..9964da6 100644
--- a/datapath-windows/ovsext/Netlink/Netlink.h
+++ b/datapath-windows/ovsext/Netlink/Netlink.h
@@ -98,6 +98,8 @@ const PNL_ATTR NlAttrFindNested(const PNL_ATTR nla,
 BOOLEAN NlAttrParse(const PNL_MSG_HDR nlMsg, UINT32 attrOffset,
                     const NL_POLICY policy[],
                     PNL_ATTR attrs[], UINT32 n_attrs);
+BOOLEAN NlParseNested(const PNL_ATTR, const NL_POLICY policy[],
+                      PNL_ATTR attrs[], UINT32 n_attrs);
 
 /* Netlink attribute validation */
 BOOLEAN NlAttrValidate(const PNL_ATTR, const PNL_POLICY);
@@ -128,5 +130,15 @@ BOOLEAN NlMsgPutHeadU16(PNL_BUFFER buf, UINT16 type, UINT16 value);
 BOOLEAN NlMsgPutHeadU32(PNL_BUFFER buf, UINT16 type, UINT32 value);
 BOOLEAN NlMsgPutHeadU64(PNL_BUFFER buf, UINT16 type, UINT64 value);
 BOOLEAN NlMsgPutHeadString(PNL_BUFFER buf, UINT16 type, PCHAR value);
+UINT32 NlMsgStartNested(PNL_BUFFER buf, UINT16 type);
+VOID NlMsgEndNested(PNL_BUFFER buf, UINT32 offset);
+VOID NlMsgPutNested(PNL_BUFFER buf, UINT16 type,
+                    const PVOID data, UINT32 size);
+
+/* These variants are convenient for iterating nested attributes. */
+#define NL_NESTED_FOR_EACH(ITER, LEFT, A)                               \
+    NL_ATTR_FOR_EACH(ITER, LEFT, NlAttrGet(A), NlAttrGetSize(A))
+#define NL_NESTED_FOR_EACH_UNSAFE(ITER, LEFT, A)                        \
+    NL_ATTR_FOR_EACH_UNSAFE(ITER, LEFT, NlAttrGet(A), NlAttrGetSize(A))
 
 #endif /* __NETLINK_H_ */
-- 
1.9.1




More information about the dev mailing list