Merge branch 'e1000-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[pandora-kernel.git] / include / net / netlink.h
index 640c26a..0bf325c 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <linux/types.h>
 #include <linux/netlink.h>
+#include <linux/jiffies.h>
 
 /* ========================================================================
  *         Netlink Messages and Attributes Interface (As Seen On TV)
  *   nlmsg_put()                       add a netlink message to an skb
  *   nlmsg_put_answer()                        callback based nlmsg_put()
  *   nlmsg_end()                       finanlize netlink message
+ *   nlmsg_get_pos()                   return current position in message
+ *   nlmsg_trim()                      trim part of message
  *   nlmsg_cancel()                    cancel message construction
  *   nlmsg_free()                      free a netlink message
  *
  * Message Sending:
  *   nlmsg_multicast()                 multicast message to several groups
  *   nlmsg_unicast()                   unicast a message to a single socket
+ *   nlmsg_notify()                    send notification message
  *
  * Message Length Calculations:
  *   nlmsg_msg_size(payload)           length of message w/o padding
@@ -62,6 +66,9 @@
  *   nlmsg_validate()                  validate netlink message incl. attrs
  *   nlmsg_for_each_attr()             loop over all attributes
  *
+ * Misc:
+ *   nlmsg_report()                    report back to application?
+ *
  * ------------------------------------------------------------------------
  *                          Attributes Interface
  * ------------------------------------------------------------------------
  *   struct nlattr                     netlink attribtue header
  *
  * Attribute Construction:
- *   nla_reserve(skb, type, len)       reserve skb tailroom for an attribute
+ *   nla_reserve(skb, type, len)       reserve room for an attribute
+ *   nla_reserve_nohdr(skb, len)       reserve room for an attribute w/o hdr
  *   nla_put(skb, type, len, data)     add attribute to skb
+ *   nla_put_nohdr(skb, len, data)     add attribute w/o hdr
  *
  * Attribute Construction for Basic Types:
  *   nla_put_u8(skb, type, value)      add u8 attribute to skb
  *   nla_ok(nla, remaining)            does nla fit into remaining bytes?
  *   nla_next(nla, remaining)          get next netlink attribute
  *   nla_validate()                    validate a stream of attributes
+ *   nla_validate_nested()             validate a stream of nested attributes
  *   nla_find()                                find attribute in stream of attributes
+ *   nla_find_nested()                 find attribute in nested attributes
  *   nla_parse()                       parse and validate stream of attrs
  *   nla_parse_nested()                        parse nested attribuets
  *   nla_for_each_attr()               loop over all attributes
+ *   nla_for_each_nested()             loop over the nested attributes
  *=========================================================================
  */
 
@@ -158,6 +170,8 @@ enum {
        NLA_FLAG,
        NLA_MSECS,
        NLA_NESTED,
+       NLA_NUL_STRING,
+       NLA_BINARY,
        __NLA_TYPE_MAX,
 };
 
@@ -166,28 +180,46 @@ enum {
 /**
  * struct nla_policy - attribute validation policy
  * @type: Type of attribute or NLA_UNSPEC
- * @minlen: Minimal length of payload required to be available
+ * @len: Type specific length of payload
  *
  * Policies are defined as arrays of this struct, the array must be
  * accessible by attribute type up to the highest identifier to be expected.
  *
+ * Meaning of `len' field:
+ *    NLA_STRING           Maximum length of string
+ *    NLA_NUL_STRING       Maximum length of string (excluding NUL)
+ *    NLA_FLAG             Unused
+ *    NLA_BINARY           Maximum length of attribute payload
+ *    All other            Exact length of attribute payload
+ *
  * Example:
  * static struct nla_policy my_policy[ATTR_MAX+1] __read_mostly = {
  *     [ATTR_FOO] = { .type = NLA_U16 },
- *     [ATTR_BAR] = { .type = NLA_STRING },
- *     [ATTR_BAZ] = { .minlen = sizeof(struct mystruct) },
+ *     [ATTR_BAR] = { .type = NLA_STRING, .len = BARSIZ },
+ *     [ATTR_BAZ] = { .len = sizeof(struct mystruct) },
  * };
  */
 struct nla_policy {
        u16             type;
-       u16             minlen;
+       u16             len;
+};
+
+/**
+ * struct nl_info - netlink source information
+ * @nlh: Netlink message header of original request
+ * @pid: Netlink PID of requesting application
+ */
+struct nl_info {
+       struct nlmsghdr         *nlh;
+       u32                     pid;
 };
 
 extern void            netlink_run_queue(struct sock *sk, unsigned int *qlen,
                                          int (*cb)(struct sk_buff *,
-                                                   struct nlmsghdr *, int *));
-extern void            netlink_queue_skip(struct nlmsghdr *nlh,
-                                          struct sk_buff *skb);
+                                                   struct nlmsghdr *));
+extern int             nlmsg_notify(struct sock *sk, struct sk_buff *skb,
+                                    u32 pid, unsigned int group, int report,
+                                    gfp_t flags);
 
 extern int             nla_validate(struct nlattr *head, int len, int maxtype,
                                     struct nla_policy *policy);
@@ -203,12 +235,18 @@ extern int                nla_memcmp(const struct nlattr *nla, const void *data,
 extern int             nla_strcmp(const struct nlattr *nla, const char *str);
 extern struct nlattr * __nla_reserve(struct sk_buff *skb, int attrtype,
                                      int attrlen);
+extern void *          __nla_reserve_nohdr(struct sk_buff *skb, int attrlen);
 extern struct nlattr * nla_reserve(struct sk_buff *skb, int attrtype,
                                    int attrlen);
+extern void *          nla_reserve_nohdr(struct sk_buff *skb, int attrlen);
 extern void            __nla_put(struct sk_buff *skb, int attrtype,
                                  int attrlen, const void *data);
+extern void            __nla_put_nohdr(struct sk_buff *skb, int attrlen,
+                                       const void *data);
 extern int             nla_put(struct sk_buff *skb, int attrtype,
                                int attrlen, const void *data);
+extern int             nla_put_nohdr(struct sk_buff *skb, int attrlen,
+                                     const void *data);
 
 /**************************************************************************
  * Netlink Messages
@@ -363,6 +401,17 @@ static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype,
                            nlmsg_attrlen(nlh, hdrlen), maxtype, policy);
 }
 
+/**
+ * nlmsg_report - need to report back to application?
+ * @nlh: netlink message header
+ *
+ * Returns 1 if a report back to the application is requested.
+ */
+static inline int nlmsg_report(struct nlmsghdr *nlh)
+{
+       return !!(nlh->nlmsg_flags & NLM_F_ECHO);
+}
+
 /**
  * nlmsg_for_each_attr - iterate over a stream of attributes
  * @pos: loop counter, set to current attribute
@@ -452,13 +501,15 @@ static inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb,
 
 /**
  * nlmsg_new - Allocate a new netlink message
- * @size: maximum size of message
+ * @payload: size of the message payload
+ * @flags: the type of memory to allocate.
  *
- * Use NLMSG_GOODSIZE if size isn't know and you need a good default size.
+ * Use NLMSG_DEFAULT_SIZE if the size of the payload isn't known
+ * and a good default is needed.
  */
-static inline struct sk_buff *nlmsg_new(int size)
+static inline struct sk_buff *nlmsg_new(size_t payload, gfp_t flags)
 {
-       return alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
+       return alloc_skb(nlmsg_total_size(payload), flags);
 }
 
 /**
@@ -474,11 +525,37 @@ static inline struct sk_buff *nlmsg_new(int size)
  */
 static inline int nlmsg_end(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
-       nlh->nlmsg_len = skb->tail - (unsigned char *) nlh;
+       nlh->nlmsg_len = skb_tail_pointer(skb) - (unsigned char *)nlh;
 
        return skb->len;
 }
 
+/**
+ * nlmsg_get_pos - return current position in netlink message
+ * @skb: socket buffer the message is stored in
+ *
+ * Returns a pointer to the current tail of the message.
+ */
+static inline void *nlmsg_get_pos(struct sk_buff *skb)
+{
+       return skb_tail_pointer(skb);
+}
+
+/**
+ * nlmsg_trim - Trim message to a mark
+ * @skb: socket buffer the message is stored in
+ * @mark: mark to trim to
+ *
+ * Trims the message to the provided mark. Returns -1.
+ */
+static inline int nlmsg_trim(struct sk_buff *skb, const void *mark)
+{
+       if (mark)
+               skb_trim(skb, (unsigned char *) mark - skb->data);
+
+       return -1;
+}
+
 /**
  * nlmsg_cancel - Cancel construction of a netlink message
  * @skb: socket buffer the message is stored in
@@ -489,9 +566,7 @@ static inline int nlmsg_end(struct sk_buff *skb, struct nlmsghdr *nlh)
  */
 static inline int nlmsg_cancel(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
-       skb_trim(skb, (unsigned char *) nlh - skb->data);
-
-       return -1;
+       return nlmsg_trim(skb, nlh);
 }
 
 /**
@@ -509,15 +584,16 @@ static inline void nlmsg_free(struct sk_buff *skb)
  * @skb: netlink message as socket buffer
  * @pid: own netlink pid to avoid sending to yourself
  * @group: multicast group id
+ * @flags: allocation flags
  */
 static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb,
-                                 u32 pid, unsigned int group)
+                                 u32 pid, unsigned int group, gfp_t flags)
 {
        int err;
 
        NETLINK_CB(skb).dst_group = group;
 
-       err = netlink_broadcast(sk, skb, pid, group, GFP_KERNEL);
+       err = netlink_broadcast(sk, skb, pid, group, flags);
        if (err > 0)
                err = 0;
 
@@ -630,6 +706,18 @@ static inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
        return (struct nlattr *) ((char *) nla + totlen);
 }
 
+/**
+ * nla_find_nested - find attribute in a set of nested attributes
+ * @nla: attribute containing the nested attributes
+ * @attrtype: type of attribute to look for
+ *
+ * Returns the first attribute which matches the specified type.
+ */
+static inline struct nlattr *nla_find_nested(struct nlattr *nla, int attrtype)
+{
+       return nla_find(nla_data(nla), nla_len(nla), attrtype);
+}
+
 /**
  * nla_parse_nested - parse nested attributes
  * @tb: destination array with maxtype+1 elements
@@ -742,16 +830,22 @@ static inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
 #define NLA_PUT_U16(skb, attrtype, value) \
        NLA_PUT_TYPE(skb, u16, attrtype, value)
 
+#define NLA_PUT_LE16(skb, attrtype, value) \
+       NLA_PUT_TYPE(skb, __le16, attrtype, value)
+
 #define NLA_PUT_U32(skb, attrtype, value) \
        NLA_PUT_TYPE(skb, u32, attrtype, value)
 
+#define NLA_PUT_BE32(skb, attrtype, value) \
+       NLA_PUT_TYPE(skb, __be32, attrtype, value)
+
 #define NLA_PUT_U64(skb, attrtype, value) \
        NLA_PUT_TYPE(skb, u64, attrtype, value)
 
 #define NLA_PUT_STRING(skb, attrtype, value) \
        NLA_PUT(skb, attrtype, strlen(value) + 1, value)
 
-#define NLA_PUT_FLAG(skb, attrtype, value) \
+#define NLA_PUT_FLAG(skb, attrtype) \
        NLA_PUT(skb, attrtype, 0, NULL)
 
 #define NLA_PUT_MSECS(skb, attrtype, jiffies) \
@@ -766,6 +860,15 @@ static inline u32 nla_get_u32(struct nlattr *nla)
        return *(u32 *) nla_data(nla);
 }
 
+/**
+ * nla_get_be32 - return payload of __be32 attribute
+ * @nla: __be32 netlink attribute
+ */
+static inline __be32 nla_get_be32(struct nlattr *nla)
+{
+       return *(__be32 *) nla_data(nla);
+}
+
 /**
  * nla_get_u16 - return payload of u16 attribute
  * @nla: u16 netlink attribute
@@ -775,6 +878,15 @@ static inline u16 nla_get_u16(struct nlattr *nla)
        return *(u16 *) nla_data(nla);
 }
 
+/**
+ * nla_get_le16 - return payload of __le16 attribute
+ * @nla: __le16 netlink attribute
+ */
+static inline __le16 nla_get_le16(struct nlattr *nla)
+{
+       return *(__le16 *) nla_data(nla);
+}
+
 /**
  * nla_get_u8 - return payload of u8 attribute
  * @nla: u8 netlink attribute
@@ -828,7 +940,7 @@ static inline unsigned long nla_get_msecs(struct nlattr *nla)
  */
 static inline struct nlattr *nla_nest_start(struct sk_buff *skb, int attrtype)
 {
-       struct nlattr *start = (struct nlattr *) skb->tail;
+       struct nlattr *start = (struct nlattr *)skb_tail_pointer(skb);
 
        if (nla_put(skb, attrtype, 0, NULL) < 0)
                return NULL;
@@ -848,7 +960,7 @@ static inline struct nlattr *nla_nest_start(struct sk_buff *skb, int attrtype)
  */
 static inline int nla_nest_end(struct sk_buff *skb, struct nlattr *start)
 {
-       start->nla_len = skb->tail - (unsigned char *) start;
+       start->nla_len = skb_tail_pointer(skb) - (unsigned char *)start;
        return skb->len;
 }
 
@@ -862,10 +974,25 @@ static inline int nla_nest_end(struct sk_buff *skb, struct nlattr *start)
  */
 static inline int nla_nest_cancel(struct sk_buff *skb, struct nlattr *start)
 {
-       if (start)
-               skb_trim(skb, (unsigned char *) start - skb->data);
+       return nlmsg_trim(skb, start);
+}
 
-       return -1;
+/**
+ * nla_validate_nested - Validate a stream of nested attributes
+ * @start: container attribute
+ * @maxtype: maximum attribute type to be expected
+ * @policy: validation policy
+ *
+ * Validates all attributes in the nested attribute stream against the
+ * specified policy. Attributes with a type exceeding maxtype will be
+ * ignored. See documenation of struct nla_policy for more details.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+static inline int nla_validate_nested(struct nlattr *start, int maxtype,
+                                     struct nla_policy *policy)
+{
+       return nla_validate(nla_data(start), nla_len(start), maxtype, policy);
 }
 
 /**
@@ -880,4 +1007,13 @@ static inline int nla_nest_cancel(struct sk_buff *skb, struct nlattr *start)
             nla_ok(pos, rem); \
             pos = nla_next(pos, &(rem)))
 
+/**
+ * nla_for_each_nested - iterate over nested attributes
+ * @pos: loop counter, set to current attribute
+ * @nla: attribute containing the nested attributes
+ * @rem: initialized to len, holds bytes currently remaining in stream
+ */
+#define nla_for_each_nested(pos, nla, rem) \
+       nla_for_each_attr(pos, nla_data(nla), nla_len(nla), rem)
+
 #endif