In a later change we would like to have  these functions inline.

Acked-by: Eitan Eliahu <elia...@vmware.com>


-----Original Message-----
From: dev [mailto:dev-boun...@openvswitch.org] On Behalf Of Ankur Sharma
Sent: Tuesday, September 02, 2014 6:05 PM
To: dev@openvswitch.org
Subject: [ovs-dev] [PATCH 5/5] Netlink.c: Added netlink put APIs.

In this change we have added the APIs for putting netlink headers, attributes 
in a buffer.

The buffer is managed through NetlinkBuf.[c|h].
---
 datapath-windows/ovsext/Netlink/Netlink.c | 403 +++++++++++++++++++++++++++++- 
 datapath-windows/ovsext/Netlink/Netlink.h |  28 +++
 2 files changed, 427 insertions(+), 4 deletions(-)

diff --git a/datapath-windows/ovsext/Netlink/Netlink.c 
b/datapath-windows/ovsext/Netlink/Netlink.c
index 90a633b..8c6b139 100644
--- a/datapath-windows/ovsext/Netlink/Netlink.c
+++ b/datapath-windows/ovsext/Netlink/Netlink.c
@@ -24,6 +24,402 @@
 #define OVS_DBG_MOD OVS_DBG_NETLINK
 #include "Debug.h"
 
+/* 
+=======================================================================
+===
+ * This file provides simple netlink get, put and validation APIs.
+ * Most of the code is on similar lines as userspace netlink implementation.
+ *
+ * TODO: Convert these methods to inline.
+ * 
+=======================================================================
+===
+ */
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds Netlink Header to the NL_BUF.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+BOOLEAN
+NlMsgPutNlHdr(PNL_BUF buf, PNL_MSG_HDR nlMsg) {
+    if ((NlBufCopyAtOffset(buf, (PCHAR)nlMsg, NLMSG_HDRLEN, 0))) {
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds Genl Header to the NL_BUF.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+BOOLEAN
+NlMsgPutGenlHdr(PNL_BUF buf, PGENL_MSG_HDR genlMsg) {
+    if ((NlBufCopyAtOffset(buf, (PCHAR)genlMsg, GENL_HDRLEN, NLMSG_HDRLEN))) {
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds OVS Header to the NL_BUF.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+BOOLEAN
+NlMsgPutOvsHdr(PNL_BUF buf, POVS_HDR ovsHdr) {
+    if ((NlBufCopyAtOffset(buf, (PCHAR)ovsHdr, OVS_HDRLEN,
+                           GENL_HDRLEN + NLMSG_HDRLEN))) {
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds data of length 'len' to the tail end of NL_BUF.
+ * Refer nl_msg_put for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+BOOLEAN
+NlMsgPutTail(PNL_BUF buf, const PCHAR data, UINT32 len) {
+    len = NLMSG_ALIGN(len);
+    if (NlBufCopyAtTail(buf, data, len)) {
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * memsets length 'len' at tail end of NL_BUF.
+ * Refer nl_msg_put_uninit for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+PCHAR
+NlMsgPutTailUninit(PNL_BUF buf, UINT32 len) {
+    len = NLMSG_ALIGN(len);
+    return NlBufCopyAtTailUninit(buf, len); }
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds an attribute to the tail end of buffer. It does
+ * not copy the attribute payload.
+ * Refer nl_msg_put_unspec_uninit for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+PCHAR
+NlMsgPutTailUnspecUninit(PNL_BUF buf, UINT16 type, UINT16 len) {
+    PCHAR ret = NULL;
+    UINT16 totalLen = NLA_HDRLEN + len;
+    PNL_ATTR nla = (PNL_ATTR)(NlMsgPutTailUninit(buf, totalLen));
+
+    if (!nla) {
+        goto done;
+    }
+
+    ret = (PCHAR)(nla + 1);
+    nla->nlaLen = totalLen;
+    nla->nlaType = type;
+
+done:
+    return ret;
+}
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds an attribute to the tail end of buffer. It copies attribute
+ * payload as well.
+ * Refer nl_msg_put_unspec for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+BOOLEAN
+NlMsgPutTailUnspec(PNL_BUF buf, UINT16 type, PCHAR data, UINT16 len) {
+    BOOLEAN ret = TRUE;
+    PCHAR nlaData = NlMsgPutTailUnspecUninit(buf, type, len);
+
+    if (!nlaData) {
+        ret = FALSE;
+        goto done;
+    }
+
+    RtlCopyMemory(nlaData, data, len);
+
+done:
+    return ret;
+}
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds an attribute of 'type' and no payload at the tail end of buffer.
+ * Refer nl_msg_put_flag for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+BOOLEAN
+NlMsgPutTailFlag(PNL_BUF buf, UINT16 type) {
+    BOOLEAN ret = TRUE;
+    PCHAR nlaData = NlMsgPutTailUnspecUninit(buf, type, 0);
+
+    if (!nlaData) {
+        ret = FALSE;
+    }
+
+    return ret;
+}
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds an attribute of 'type' and 8 bit payload at the tail end of buffer.
+ * Refer nl_msg_put_u8 for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+BOOLEAN
+NlMsgPutTailU8(PNL_BUF buf, UINT16 type, UINT8 value) {
+    return (NlMsgPutTailUnspec(buf, type, (PCHAR)(&value), 
+sizeof(value))); }
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds an attribute of 'type' and 16 bit payload at the tail end of buffer.
+ * Refer nl_msg_put_u16 for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+BOOLEAN
+NlMsgPutTailU16(PNL_BUF buf, UINT16 type, UINT16 value) {
+    return (NlMsgPutTailUnspec(buf, type, (PCHAR)(&value), 
+sizeof(value))); }
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds an attribute of 'type' and 32 bit payload at the tail end of buffer.
+ * Refer nl_msg_put_u32 for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+BOOLEAN
+NlMsgPutTailU32(PNL_BUF buf, UINT16 type, UINT32 value) {
+    return (NlMsgPutTailUnspec(buf, type, (PCHAR)(&value), 
+sizeof(value))); }
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds an attribute of 'type' and 64 bit payload at the tail end of buffer.
+ * Refer nl_msg_put_u64 for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+BOOLEAN
+NlMsgPutTailU64(PNL_BUF buf, UINT16 type, UINT64 value) {
+    return (NlMsgPutTailUnspec(buf, type, (PCHAR)(&value), 
+sizeof(value))); }
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds an attribute of 'type' and string payload.
+ * Refer nl_msg_put_string for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+BOOLEAN
+NlMsgPutTailString(PNL_BUF buf, UINT16 type, PCHAR value) {
+    size_t strLen = strlen(value) + 1;
+#ifdef DBG
+    /* Attribute length should come within 16 bits (NL_ATTR).
+     * Not a likely case, hence validation only in debug mode. */
+    if ((strLen + PAD_SIZE(strLen, NLA_ALIGNTO)) > MAXUINT16) {
+        return FALSE;
+    }
+#endif
+
+    /* typecast to keep compiler happy */
+    return (NlMsgPutTailUnspec(buf, type, value,
+                               (UINT16)strLen)); }
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds data of length 'len' to the head of NL_BUF.
+ * Refer nl_msg_push for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+BOOLEAN
+NlMsgPutHead(PNL_BUF buf, const PCHAR data, UINT32 len) {
+    len = NLMSG_ALIGN(len);
+    if (NlBufCopyAtHead(buf, data, len)) {
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * memsets length 'len' at head of NL_BUF.
+ * Refer nl_msg_push_uninit for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+PCHAR
+NlMsgPutHeadUninit(PNL_BUF buf, UINT32 len) {
+    len = NLMSG_ALIGN(len);
+    return NlBufCopyAtHeadUninit(buf, len); }
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds an attribute to the head of buffer. It does
+ * not copy the attribute payload.
+ * Refer nl_msg_push_unspec_uninit for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+PCHAR
+NlMsgPutHeadUnspecUninit(PNL_BUF buf, UINT16 type, UINT16 len) {
+    PCHAR ret = NULL;
+    UINT16 totalLen = NLA_HDRLEN + len;
+    PNL_ATTR nla = (PNL_ATTR)(NlMsgPutHeadUninit(buf, totalLen));
+
+    if (!nla) {
+        goto done;
+    }
+
+    ret = (PCHAR)(nla + 1);
+    nla->nlaLen = totalLen;
+    nla->nlaType = type;
+
+done:
+    return ret;
+}
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds an attribute to the head of buffer. It copies attribute
+ * payload as well.
+ * Refer nl_msg_push_unspec for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+BOOLEAN
+NlMsgPutHeadUnspec(PNL_BUF buf, UINT16 type, PCHAR data, UINT16 len) {
+    BOOLEAN ret = TRUE;
+    PCHAR nlaData = NlMsgPutHeadUnspecUninit(buf, type, len);
+
+    if (!nlaData) {
+        ret = FALSE;
+        goto done;
+    }
+
+    RtlCopyMemory(nlaData, data, len);
+
+done:
+    return ret;
+}
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds an attribute of 'type' and no payload at the head of buffer.
+ * Refer nl_msg_push_flag for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+BOOLEAN
+NlMsgPutHeadFlag(PNL_BUF buf, UINT16 type) {
+    BOOLEAN ret = TRUE;
+    PCHAR nlaData = NlMsgPutHeadUnspecUninit(buf, type, 0);
+
+    if (!nlaData) {
+        ret = FALSE;
+    }
+
+    return ret;
+}
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds an attribute of 'type' and 8 bit payload at the head of buffer.
+ * Refer nl_msg_push_u8 for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+BOOLEAN
+NlMsgPutHeadU8(PNL_BUF buf, UINT16 type, UINT8 value) {
+    return (NlMsgPutHeadUnspec(buf, type, (PCHAR)(&value), 
+sizeof(value))); }
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds an attribute of 'type' and 16 bit payload at the head of buffer.
+ * Refer nl_msg_push_u16 for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+BOOLEAN
+NlMsgPutHeadU16(PNL_BUF buf, UINT16 type, UINT16 value) {
+    return (NlMsgPutHeadUnspec(buf, type, (PCHAR)(&value), 
+sizeof(value))); }
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds an attribute of 'type' and 32 bit payload at the head of buffer.
+ * Refer nl_msg_push_u32 for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+BOOLEAN
+NlMsgPutHeadU32(PNL_BUF buf, UINT16 type, UINT32 value) {
+    return (NlMsgPutHeadUnspec(buf, type, (PCHAR)(&value), 
+sizeof(value))); }
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds an attribute of 'type' and 64 bit payload at the head of buffer.
+ * Refer nl_msg_push_u64 for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+BOOLEAN
+NlMsgPutHeadU64(PNL_BUF buf, UINT16 type, UINT64 value) {
+    return (NlMsgPutHeadUnspec(buf, type, (PCHAR)(&value), 
+sizeof(value))); }
+
+/*
+ * 
+-----------------------------------------------------------------------
+----
+ * Adds an attribute of 'type' and string payload.
+ * Refer nl_msg_push_string for more details.
+ * 
+-----------------------------------------------------------------------
+----
+ */
+BOOLEAN
+NlMsgPutHeadString(PNL_BUF buf, UINT16 type, PCHAR value) {
+    size_t strLen = strlen(value) + 1;
+#ifdef DBG
+    /* Attribute length should come within 16 bits (NL_ATTR).
+     * Not a likely case, hence validation only in debug mode. */
+    if ((strLen + PAD_SIZE(strLen, NLA_ALIGNTO)) > MAXUINT16) {
+        return FALSE;
+    }
+#endif
+
+    /* typecast to keep compiler happy */
+    return (NlMsgPutHeadUnspec(buf, type, value,
+                               (UINT16)strLen)); }
+
+/* Accessing netlink message payload */
+
 /*
  * ---------------------------------------------------------------------------
  * Netlink message accessing the payload.
@@ -173,7 +569,7 @@ NlAttrMaxLen(NL_ATTR_TYPE type)
     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_STRING: return MAXUINT16;
     case NL_A_FLAG: return SIZE_MAX;
     case NL_A_NESTED: return SIZE_MAX;
     case N_NL_ATTR_TYPES:
@@ -408,8 +804,7 @@ NlAttrFindNested(const PNL_ATTR nla, UINT16 type)
  * 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).
+ * Returns BOOLEAN to indicate success/failure.
  *----------------------------------------------------------------------------
  */
 BOOLEAN NlAttrParse(const PNL_MSG_HDR nlMsg, UINT32 attrOffset, @@ -421,7 
+816,7 @@ BOOLEAN NlAttrParse(const PNL_MSG_HDR nlMsg, UINT32 attrOffset,
     UINT32 iter;
     BOOLEAN ret = FALSE;
 
-    memset(attrs, 0, n_attrs * sizeof *attrs);
+    RtlZeroMemory(attrs, n_attrs * sizeof *attrs);
 
     if ((NlMsgSize(nlMsg) < attrOffset) || (!(NlMsgAttrLen(nlMsg)))) {
         OVS_LOG_WARN("No attributes in nlMsg: %p at offset: %d", diff --git 
a/datapath-windows/ovsext/Netlink/Netlink.h 
b/datapath-windows/ovsext/Netlink/Netlink.h
index 0edc2fa..04fd536 100644
--- a/datapath-windows/ovsext/Netlink/Netlink.h
+++ b/datapath-windows/ovsext/Netlink/Netlink.h
@@ -19,6 +19,7 @@
 
 #include "Types.h"
 #include "NetlinkProto.h"
+#include "NetlinkBuf.h"
 
 /* Netlink attribute types. */
 typedef enum
@@ -101,4 +102,31 @@ BOOLEAN NlAttrParse(const PNL_MSG_HDR nlMsg, UINT32 
attrOffset,
 /* Netlink attribute validation */
 BOOLEAN NlAttrValidate(const PNL_ATTR, const PNL_POLICY);
 
+/* Put APis */
+BOOLEAN NlMsgPutNlHdr(PNL_BUF buf, PNL_MSG_HDR nlMsg); BOOLEAN 
+NlMsgPutGenlHdr(PNL_BUF buf, PGENL_MSG_HDR genlMsg); BOOLEAN 
+NlMsgPutOvsHdr(PNL_BUF buf, POVS_HDR ovsHdr);
+
+BOOLEAN NlMsgPutTail(PNL_BUF buf, const PCHAR data, UINT32 len); PCHAR 
+NlMsgPutTailUninit(PNL_BUF buf, UINT32 len); PCHAR 
+NlMsgPutTailUnspecUninit(PNL_BUF buf, UINT16 type, UINT16 len); BOOLEAN 
+NlMsgPutTailUnspec(PNL_BUF buf, UINT16 type, PCHAR data, UINT16 len); 
+BOOLEAN NlMsgPutTailFlag(PNL_BUF buf, UINT16 type); BOOLEAN 
+NlMsgPutTailU8(PNL_BUF buf, UINT16 type, UINT8 value); BOOLEAN 
+NlMsgPutTailU16(PNL_BUF buf, UINT16 type, UINT16 value); BOOLEAN 
+NlMsgPutTailU32(PNL_BUF buf, UINT16 type, UINT32 value); BOOLEAN 
+NlMsgPutTailU64(PNL_BUF buf, UINT16 type, UINT64 value); BOOLEAN 
+NlMsgPutTailString(PNL_BUF buf, UINT16 type, PCHAR value);
+
+BOOLEAN NlMsgPutHead(PNL_BUF buf, const PCHAR data, UINT32 len); PCHAR 
+NlMsgPutHeadUninit(PNL_BUF buf, UINT32 len); PCHAR 
+NlMsgPutHeadUnspecUninit(PNL_BUF buf, UINT16 type, UINT16 len); BOOLEAN 
+NlMsgPutHeadUnspec(PNL_BUF buf, UINT16 type, PCHAR data, UINT16 len); 
+BOOLEAN NlMsgPutHeadFlag(PNL_BUF buf, UINT16 type); BOOLEAN 
+NlMsgPutHeadU8(PNL_BUF buf, UINT16 type, UINT8 value); BOOLEAN 
+NlMsgPutHeadU16(PNL_BUF buf, UINT16 type, UINT16 value); BOOLEAN 
+NlMsgPutHeadU32(PNL_BUF buf, UINT16 type, UINT32 value); BOOLEAN 
+NlMsgPutHeadU64(PNL_BUF buf, UINT16 type, UINT64 value); BOOLEAN 
+NlMsgPutHeadString(PNL_BUF buf, UINT16 type, PCHAR value);
+
 #endif /* __NETLINK_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=yTvML8OxA42Jb6ViHe7fUXbvPVOYDPVq87w43doxtlY%3D%0A&m=2lDkr624ExQLczCtZfvO5gZ7JQ1kQEJKKy%2BCiCLiySM%3D%0A&s=6cc410ff9c3cf2c6aed2ff4051eb9e961608065273360cf224e5cc56c64076a7
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to