Skip to content

Commit

Permalink
datapath-windows/Netlink: Nested attributes put/parse.
Browse files Browse the repository at this point in the history
Added APIs for creating and parsing nested netlink attributes.
APIs are on similar lines as userspace netlink code.

Signed-off-by: Ankur Sharma <[email protected]>
Acked-by: Nithin Raju <[email protected]>
Acked-by: Alin Gabriel Serdean <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
ankursh authored and blp committed Sep 12, 2014
1 parent 402bf08 commit 988672a
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 3 deletions.
92 changes: 89 additions & 3 deletions datapath-windows/ovsext/Netlink/Netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

/*
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
12 changes: 12 additions & 0 deletions datapath-windows/ovsext/Netlink/Netlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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_ */

0 comments on commit 988672a

Please sign in to comment.