From: Ben Pfaff Date: Wed, 7 Jan 2009 01:06:48 +0000 (-0800) Subject: Make nl_policy_parse() compatible with non-Generic Netlink packets. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2ecd1a1d134f0669e80e8e5cd0b182fda7dd5613;p=openvswitch Make nl_policy_parse() compatible with non-Generic Netlink packets. Some packets that are not Generic Netlink packets nevertheless use its attribute format. By making the caller pass in the offset to the attributes we can support these packet formats too. (Another approach would be to make the caller pull off the headers.) --- diff --git a/lib/dpif.c b/lib/dpif.c index af15f8f1..3e4c3ce7 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -167,7 +167,8 @@ dpif_recv_openflow(struct dpif *dp, int dp_idx, struct ofpbuf **bufferp, 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; } @@ -321,7 +322,8 @@ query_datapath(int *dp_idx, int *multicast_group, const char *dp_name) 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); diff --git a/lib/netlink.c b/lib/netlink.c index 131ed817..e1b27a78 100644 --- a/lib/netlink.c +++ b/lib/netlink.c @@ -761,12 +761,16 @@ static const size_t attr_len_range[][2] = { [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; @@ -785,7 +789,7 @@ nl_policy_parse(const struct ofpbuf *msg, const struct nl_policy policy[], } } - 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; @@ -886,8 +890,8 @@ static int do_lookup_genl_family(const char *name) 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; diff --git a/lib/netlink.h b/lib/netlink.h index e287457b..d9269c7c 100644 --- a/lib/netlink.h +++ b/lib/netlink.h @@ -1,4 +1,4 @@ -/* 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 @@ -133,7 +133,8 @@ struct nl_policy 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); /* Miscellaneous. */ diff --git a/vswitchd/brcompat.c b/vswitchd/brcompat.c index 39f0b4a7..439d9a80 100644 --- a/vswitchd/brcompat.c +++ b/vswitchd/brcompat.c @@ -103,8 +103,9 @@ lookup_brc_multicast_group(int *multicast_group) 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; @@ -300,8 +301,8 @@ brc_handle_dp_cmd(struct ofpbuf *buffer, bool add) 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; } @@ -338,8 +339,8 @@ brc_handle_port_cmd(struct ofpbuf *buffer, bool add) 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; }