]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - lib/nlattr.c
xps: Transmit Packet Steering
[net-next-2.6.git] / lib / nlattr.c
index 80009a24e21dd553a6204310b083ccd5e8bf6cf3..00e8a02681a6f219251622337375b15fb3bc4acc 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/types.h>
 #include <net/netlink.h>
 
-static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = {
+static const u16 nla_attr_minlen[NLA_TYPE_MAX+1] = {
        [NLA_U8]        = sizeof(u8),
        [NLA_U16]       = sizeof(u16),
        [NLA_U32]       = sizeof(u32),
@@ -23,7 +23,7 @@ static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = {
        [NLA_NESTED]    = NLA_HDRLEN,
 };
 
-static int validate_nla(struct nlattr *nla, int maxtype,
+static int validate_nla(const struct nlattr *nla, int maxtype,
                        const struct nla_policy *policy)
 {
        const struct nla_policy *pt;
@@ -115,10 +115,10 @@ static int validate_nla(struct nlattr *nla, int maxtype,
  *
  * Returns 0 on success or a negative error code.
  */
-int nla_validate(struct nlattr *head, int len, int maxtype,
+int nla_validate(const struct nlattr *head, int len, int maxtype,
                 const struct nla_policy *policy)
 {
-       struct nlattr *nla;
+       const struct nlattr *nla;
        int rem, err;
 
        nla_for_each_attr(nla, head, len, rem) {
@@ -132,6 +132,32 @@ errout:
        return err;
 }
 
+/**
+ * nla_policy_len - Determin the max. length of a policy
+ * @policy: policy to use
+ * @n: number of policies
+ *
+ * Determines the max. length of the policy.  It is currently used
+ * to allocated Netlink buffers roughly the size of the actual
+ * message.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int
+nla_policy_len(const struct nla_policy *p, int n)
+{
+       int i, len = 0;
+
+       for (i = 0; i < n; i++) {
+               if (p->len)
+                       len += nla_total_size(p->len);
+               else if (nla_attr_minlen[p->type])
+                       len += nla_total_size(nla_attr_minlen[p->type]);
+       }
+
+       return len;
+}
+
 /**
  * nla_parse - Parse a stream of attributes into a tb buffer
  * @tb: destination array with maxtype+1 elements
@@ -147,10 +173,10 @@ errout:
  *
  * Returns 0 on success or a negative error code.
  */
-int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
-             const struct nla_policy *policy)
+int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
+             int len, const struct nla_policy *policy)
 {
-       struct nlattr *nla;
+       const struct nlattr *nla;
        int rem, err;
 
        memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
@@ -165,7 +191,7 @@ int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
                                        goto errout;
                        }
 
-                       tb[type] = nla;
+                       tb[type] = (struct nlattr *)nla;
                }
        }
 
@@ -186,14 +212,14 @@ errout:
  *
  * Returns the first attribute in the stream matching the specified type.
  */
-struct nlattr *nla_find(struct nlattr *head, int len, int attrtype)
+struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype)
 {
-       struct nlattr *nla;
+       const struct nlattr *nla;
        int rem;
 
        nla_for_each_attr(nla, head, len, rem)
                if (nla_type(nla) == attrtype)
-                       return nla;
+                       return (struct nlattr *)nla;
 
        return NULL;
 }
@@ -467,6 +493,7 @@ EXPORT_SYMBOL(nla_append);
 #endif
 
 EXPORT_SYMBOL(nla_validate);
+EXPORT_SYMBOL(nla_policy_len);
 EXPORT_SYMBOL(nla_parse);
 EXPORT_SYMBOL(nla_find);
 EXPORT_SYMBOL(nla_strlcpy);