goto error;
}
- if (!nl_policy_parse(buffer, openflow_policy, attrs,
+ if (!nl_policy_parse(buffer, NLMSG_HDRLEN + GENL_HDRLEN,
+ openflow_policy, attrs,
ARRAY_SIZE(openflow_policy))) {
goto error;
}
nl_sock_destroy(sock);
return retval;
}
- if (!nl_policy_parse(reply, openflow_multicast_policy, attrs,
+ if (!nl_policy_parse(reply, NLMSG_HDRLEN + GENL_HDRLEN,
+ openflow_multicast_policy, attrs,
ARRAY_SIZE(openflow_multicast_policy))) {
nl_sock_destroy(sock);
ofpbuf_delete(reply);
[NL_A_NESTED] = { NLMSG_HDRLEN, SIZE_MAX },
};
-/* Parses the Generic Netlink payload of 'msg' as a sequence of Netlink
+/* Parses the 'msg' starting at the given 'nla_offset' as a sequence of Netlink
* attributes. 'policy[i]', for 0 <= i < n_attrs, specifies how the attribute
* with nla_type == i is parsed; a pointer to attribute i is stored in
- * attrs[i]. Returns true if successful, false on failure. */
+ * attrs[i]. Returns true if successful, false on failure.
+ *
+ * If the Netlink attributes in 'msg' follow a Netlink header and a Generic
+ * Netlink header, then 'nla_offset' should be NLMSG_HDRLEN + GENL_HDRLEN. */
bool
-nl_policy_parse(const struct ofpbuf *msg, const struct nl_policy policy[],
+nl_policy_parse(const struct ofpbuf *msg, size_t nla_offset,
+ const struct nl_policy policy[],
struct nlattr *attrs[], size_t n_attrs)
{
void *p, *tail;
}
}
- p = ofpbuf_at(msg, NLMSG_HDRLEN + GENL_HDRLEN, 0);
+ p = ofpbuf_at(msg, nla_offset, 0);
if (p == NULL) {
VLOG_DBG_RL(&rl, "missing headers in nl_policy_parse");
return false;
return -retval;
}
- if (!nl_policy_parse(reply, family_policy, attrs,
- ARRAY_SIZE(family_policy))) {
+ if (!nl_policy_parse(reply, NLMSG_HDRLEN + GENL_HDRLEN,
+ family_policy, attrs, ARRAY_SIZE(family_policy))) {
nl_sock_destroy(sock);
ofpbuf_delete(reply);
return -EPROTO;
-/* Copyright (c) 2008 The Board of Trustees of The Leland Stanford
+/* Copyright (c) 2008, 2009 The Board of Trustees of The Leland Stanford
* Junior University
*
* We are making the OpenFlow specification and associated documentation
bool optional;
};
-bool nl_policy_parse(const struct ofpbuf *, const struct nl_policy[],
+bool nl_policy_parse(const struct ofpbuf *, size_t offset,
+ const struct nl_policy[],
struct nlattr *[], size_t n_attrs);
\f
/* Miscellaneous. */
nl_sock_destroy(sock);
return retval;
}
- if (!nl_policy_parse(reply, brc_multicast_policy, attrs,
- ARRAY_SIZE(brc_multicast_policy))) {
+ if (!nl_policy_parse(reply, NLMSG_HDRLEN + GENL_HDRLEN,
+ brc_multicast_policy, attrs,
+ ARRAY_SIZE(brc_multicast_policy))) {
nl_sock_destroy(sock);
ofpbuf_delete(reply);
return EPROTO;
const char *dp_name;
struct ofpbuf msg;
- if (!nl_policy_parse(buffer, brc_dp_policy, attrs,
- ARRAY_SIZE(brc_dp_policy))) {
+ if (!nl_policy_parse(buffer, NLMSG_HDRLEN + GENL_HDRLEN, brc_dp_policy,
+ attrs, ARRAY_SIZE(brc_dp_policy))) {
return EINVAL;
}
struct nlattr *attrs[ARRAY_SIZE(brc_port_policy)];
const char *dp_name, *port_name;
- if (!nl_policy_parse(buffer, brc_port_policy, attrs,
- ARRAY_SIZE(brc_port_policy))) {
+ if (!nl_policy_parse(buffer, NLMSG_HDRLEN + GENL_HDRLEN, brc_port_policy,
+ attrs, ARRAY_SIZE(brc_port_policy))) {
return EINVAL;
}