]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/netlink/attr.c
[NETLINK]: Introduce nested and byteorder flag to netlink attribute
[net-next-2.6.git] / net / netlink / attr.c
index c591212793ee4d7cbd981cabe753a5825f68b4fc..ec39d12c2423347463e766fc83bda5ef9861901a 100644 (file)
@@ -27,12 +27,12 @@ static int validate_nla(struct nlattr *nla, int maxtype,
                        const struct nla_policy *policy)
 {
        const struct nla_policy *pt;
-       int minlen = 0, attrlen = nla_len(nla);
+       int minlen = 0, attrlen = nla_len(nla), type = nla_type(nla);
 
-       if (nla->nla_type <= 0 || nla->nla_type > maxtype)
+       if (type <= 0 || type > maxtype)
                return 0;
 
-       pt = &policy[nla->nla_type];
+       pt = &policy[type];
 
        BUG_ON(pt->type > NLA_TYPE_MAX);
 
@@ -72,6 +72,17 @@ static int validate_nla(struct nlattr *nla, int maxtype,
                        return -ERANGE;
                break;
 
+       case NLA_NESTED_COMPAT:
+               if (attrlen < pt->len)
+                       return -ERANGE;
+               if (attrlen < NLA_ALIGN(pt->len))
+                       break;
+               if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN)
+                       return -ERANGE;
+               nla = nla_data(nla) + NLA_ALIGN(pt->len);
+               if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN + nla_len(nla))
+                       return -ERANGE;
+               break;
        default:
                if (pt->len)
                        minlen = pt->len;
@@ -138,7 +149,7 @@ int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
        memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
 
        nla_for_each_attr(nla, head, len, rem) {
-               u16 type = nla->nla_type;
+               u16 type = nla_type(nla);
 
                if (type > 0 && type <= maxtype) {
                        if (policy) {
@@ -174,7 +185,7 @@ struct nlattr *nla_find(struct nlattr *head, int len, int attrtype)
        int rem;
 
        nla_for_each_attr(nla, head, len, rem)
-               if (nla->nla_type == attrtype)
+               if (nla_type(nla) == attrtype)
                        return nla;
 
        return NULL;