Make nl_policy_parse() compatible with non-Generic Netlink packets.
authorBen Pfaff <blp@nicira.com>
Wed, 7 Jan 2009 01:06:48 +0000 (17:06 -0800)
committerBen Pfaff <blp@nicira.com>
Fri, 23 Jan 2009 18:43:44 +0000 (10:43 -0800)
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.)

lib/dpif.c
lib/netlink.c
lib/netlink.h
vswitchd/brcompat.c

index af15f8f1b638cca23a1d52cd63a80dcbe4cdb9f4..3e4c3ce768f03b4d8ce724cc0a748959e48f8514 100644 (file)
@@ -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);
index 131ed817e1018771078f1b73a078684fd03ee09b..e1b27a78c7c1b826a4382f1a7bdfe3d6efac17a5 100644 (file)
@@ -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;
index e287457b47f1f14c64f713498bcfb4abbe1f71d7..d9269c7c51b9884ae67cfac49162900c4d08ee7a 100644 (file)
@@ -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);
 \f
 /* Miscellaneous. */
index 39f0b4a7b28b1fe362c5a113a440199a746737a0..439d9a8028691dbacbf242650e150ab8a0a7aa45 100644 (file)
@@ -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;
     }