Added APIs for creating and parsing nested netlink attributes. APIs are on similar lines as userspace netlink code.
Signed-off-by: Ankur Sharma <ankursha...@vmware.com> --- datapath-windows/ovsext/Netlink/Netlink.c | 94 ++++++++++++++++++++++++++++++- datapath-windows/ovsext/Netlink/Netlink.h | 12 ++++ 2 files changed, 103 insertions(+), 3 deletions(-) diff --git a/datapath-windows/ovsext/Netlink/Netlink.c b/datapath-windows/ovsext/Netlink/Netlink.c index 99cdc0e..b304e13 100644 --- a/datapath-windows/ovsext/Netlink/Netlink.c +++ b/datapath-windows/ovsext/Netlink/Netlink.c @@ -418,6 +418,75 @@ 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); + + UNREFERENCED_PARAMETER(data); + UNREFERENCED_PARAMETER(size); + + ASSERT(offset); + + ASSERT(NlMsgPutTail(buf, data, size)); + + NlMsgEndNested(buf, offset); + + return; +} + /* Accessing netlink message payload */ /* @@ -807,9 +876,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 +932,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 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev