/* *---------------------------------------------------------------------------- * 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 BOOLEAN to indicate success/failure. *---------------------------------------------------------------------------- */ BOOLEAN NlAttrParse(const PNL_MSG_HDR nlMsg, UINT32 attrOffset, UINT32 totalAttrLen, const NL_POLICY policy[], PNL_ATTR attrs[], UINT32 n_attrs) { PNL_ATTR nla; UINT32 left; UINT32 iter; BOOLEAN ret = FALSE; RtlZeroMemory(attrs, n_attrs * sizeof *attrs); /* There is nothing to parse */ if (!(NlMsgAttrsLen(nlMsg))) { ret = TRUE; goto done; } if ((NlMsgSize(nlMsg) < attrOffset)) { OVS_LOG_WARN("No attributes in nlMsg: %p at offset: %d", nlMsg, attrOffset); goto done; } NL_ATTR_FOR_EACH (nla, left, NlMsgAt(nlMsg, attrOffset), totalAttrLen) { 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; } }
/* *---------------------------------------------------------------------------- * Traverses all attributes in received buffer in order to insure all are valid *---------------------------------------------------------------------------- */ BOOLEAN NlValidateAllAttrs(const PNL_MSG_HDR nlMsg, UINT32 attrOffset, UINT32 totalAttrLen, const NL_POLICY policy[], const UINT32 numPolicy) { PNL_ATTR nla; INT left; BOOLEAN ret = TRUE; if ((NlMsgSize(nlMsg) < attrOffset)) { OVS_LOG_WARN("No attributes in nlMsg: %p at offset: %d", nlMsg, attrOffset); ret = FALSE; goto done; } NL_ATTR_FOR_EACH_UNSAFE(nla, left, NlMsgAt(nlMsg, attrOffset), totalAttrLen) { if (!NlAttrIsValid(nla, left)) { ret = FALSE; goto done; } UINT16 type = NlAttrType(nla); if (type < numPolicy && 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)) { ret = FALSE; goto done; } } } done: return ret; }