]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/netlabel/netlabel_mgmt.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
[linux-2.6-omap-h63xx.git] / net / netlabel / netlabel_mgmt.c
index 0ac314f18ad146296b713da535202b54563e36ca..22c19126780899b464b70f3f4e545b29f1e51f65 100644 (file)
 #include <net/genetlink.h>
 #include <net/netlabel.h>
 #include <net/cipso_ipv4.h>
+#include <asm/atomic.h>
 
 #include "netlabel_domainhash.h"
 #include "netlabel_user.h"
 #include "netlabel_mgmt.h"
 
+/* NetLabel configured protocol counter */
+atomic_t netlabel_mgmt_protocount = ATOMIC_INIT(0);
+
 /* Argument struct for netlbl_domhsh_walk() */
 struct netlbl_domhsh_walk_arg {
        struct netlink_callback *nl_cb;
@@ -59,7 +63,7 @@ static struct genl_family netlbl_mgmt_gnl_family = {
 };
 
 /* NetLabel Netlink attribute policy */
-static struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = {
+static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = {
        [NLBL_MGMT_A_DOMAIN] = { .type = NLA_NUL_STRING },
        [NLBL_MGMT_A_PROTOCOL] = { .type = NLA_U32 },
        [NLBL_MGMT_A_VERSION] = { .type = NLA_U32 },
@@ -87,11 +91,14 @@ static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info)
        struct netlbl_dom_map *entry = NULL;
        size_t tmp_size;
        u32 tmp_val;
+       struct netlbl_audit audit_info;
 
        if (!info->attrs[NLBL_MGMT_A_DOMAIN] ||
            !info->attrs[NLBL_MGMT_A_PROTOCOL])
                goto add_failure;
 
+       netlbl_netlink_auditinfo(skb, &audit_info);
+
        entry = kzalloc(sizeof(*entry), GFP_KERNEL);
        if (entry == NULL) {
                ret_val = -ENOMEM;
@@ -108,7 +115,7 @@ static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info)
 
        switch (entry->type) {
        case NETLBL_NLTYPE_UNLABELED:
-               ret_val = netlbl_domhsh_add(entry, NETLINK_CB(skb).sid);
+               ret_val = netlbl_domhsh_add(entry, &audit_info);
                break;
        case NETLBL_NLTYPE_CIPSOV4:
                if (!info->attrs[NLBL_MGMT_A_CV4DOI])
@@ -125,7 +132,7 @@ static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info)
                        rcu_read_unlock();
                        goto add_failure;
                }
-               ret_val = netlbl_domhsh_add(entry, NETLINK_CB(skb).sid);
+               ret_val = netlbl_domhsh_add(entry, &audit_info);
                rcu_read_unlock();
                break;
        default:
@@ -156,12 +163,15 @@ add_failure:
 static int netlbl_mgmt_remove(struct sk_buff *skb, struct genl_info *info)
 {
        char *domain;
+       struct netlbl_audit audit_info;
 
        if (!info->attrs[NLBL_MGMT_A_DOMAIN])
                return -EINVAL;
 
+       netlbl_netlink_auditinfo(skb, &audit_info);
+
        domain = nla_data(info->attrs[NLBL_MGMT_A_DOMAIN]);
-       return netlbl_domhsh_remove(domain, NETLINK_CB(skb).sid);
+       return netlbl_domhsh_remove(domain, &audit_info);
 }
 
 /**
@@ -182,12 +192,9 @@ static int netlbl_mgmt_listall_cb(struct netlbl_dom_map *entry, void *arg)
        struct netlbl_domhsh_walk_arg *cb_arg = arg;
        void *data;
 
-       data = netlbl_netlink_hdr_put(cb_arg->skb,
-                                     NETLINK_CB(cb_arg->nl_cb->skb).pid,
-                                     cb_arg->seq,
-                                     netlbl_mgmt_gnl_family.id,
-                                     NLM_F_MULTI,
-                                     NLBL_MGMT_C_LISTALL);
+       data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).pid,
+                          cb_arg->seq, &netlbl_mgmt_gnl_family,
+                          NLM_F_MULTI, NLBL_MGMT_C_LISTALL);
        if (data == NULL)
                goto listall_cb_failure;
 
@@ -264,10 +271,13 @@ static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info)
        int ret_val = -EINVAL;
        struct netlbl_dom_map *entry = NULL;
        u32 tmp_val;
+       struct netlbl_audit audit_info;
 
        if (!info->attrs[NLBL_MGMT_A_PROTOCOL])
                goto adddef_failure;
 
+       netlbl_netlink_auditinfo(skb, &audit_info);
+
        entry = kzalloc(sizeof(*entry), GFP_KERNEL);
        if (entry == NULL) {
                ret_val = -ENOMEM;
@@ -277,8 +287,7 @@ static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info)
 
        switch (entry->type) {
        case NETLBL_NLTYPE_UNLABELED:
-               ret_val = netlbl_domhsh_add_default(entry,
-                                                   NETLINK_CB(skb).sid);
+               ret_val = netlbl_domhsh_add_default(entry, &audit_info);
                break;
        case NETLBL_NLTYPE_CIPSOV4:
                if (!info->attrs[NLBL_MGMT_A_CV4DOI])
@@ -295,8 +304,7 @@ static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info)
                        rcu_read_unlock();
                        goto adddef_failure;
                }
-               ret_val = netlbl_domhsh_add_default(entry,
-                                                   NETLINK_CB(skb).sid);
+               ret_val = netlbl_domhsh_add_default(entry, &audit_info);
                rcu_read_unlock();
                break;
        default:
@@ -324,7 +332,11 @@ adddef_failure:
  */
 static int netlbl_mgmt_removedef(struct sk_buff *skb, struct genl_info *info)
 {
-       return netlbl_domhsh_remove_default(NETLINK_CB(skb).sid);
+       struct netlbl_audit audit_info;
+
+       netlbl_netlink_auditinfo(skb, &audit_info);
+
+       return netlbl_domhsh_remove_default(&audit_info);
 }
 
 /**
@@ -345,15 +357,11 @@ static int netlbl_mgmt_listdef(struct sk_buff *skb, struct genl_info *info)
        void *data;
        struct netlbl_dom_map *entry;
 
-       ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (ans_skb == NULL)
                return -ENOMEM;
-       data = netlbl_netlink_hdr_put(ans_skb,
-                                     info->snd_pid,
-                                     info->snd_seq,
-                                     netlbl_mgmt_gnl_family.id,
-                                     0,
-                                     NLBL_MGMT_C_LISTDEF);
+       data = genlmsg_put_reply(ans_skb, info, &netlbl_mgmt_gnl_family,
+                                0, NLBL_MGMT_C_LISTDEF);
        if (data == NULL)
                goto listdef_failure;
 
@@ -379,7 +387,7 @@ static int netlbl_mgmt_listdef(struct sk_buff *skb, struct genl_info *info)
 
        genlmsg_end(ans_skb, data);
 
-       ret_val = genlmsg_unicast(ans_skb, info->snd_pid);
+       ret_val = genlmsg_reply(ans_skb, info);
        if (ret_val != 0)
                goto listdef_failure;
        return 0;
@@ -411,12 +419,9 @@ static int netlbl_mgmt_protocols_cb(struct sk_buff *skb,
        int ret_val = -ENOMEM;
        void *data;
 
-       data = netlbl_netlink_hdr_put(skb,
-                                     NETLINK_CB(cb->skb).pid,
-                                     cb->nlh->nlmsg_seq,
-                                     netlbl_mgmt_gnl_family.id,
-                                     NLM_F_MULTI,
-                                     NLBL_MGMT_C_PROTOCOLS);
+       data = genlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
+                          &netlbl_mgmt_gnl_family, NLM_F_MULTI,
+                          NLBL_MGMT_C_PROTOCOLS);
        if (data == NULL)
                goto protocols_cb_failure;
 
@@ -481,15 +486,11 @@ static int netlbl_mgmt_version(struct sk_buff *skb, struct genl_info *info)
        struct sk_buff *ans_skb = NULL;
        void *data;
 
-       ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (ans_skb == NULL)
                return -ENOMEM;
-       data = netlbl_netlink_hdr_put(ans_skb,
-                                     info->snd_pid,
-                                     info->snd_seq,
-                                     netlbl_mgmt_gnl_family.id,
-                                     0,
-                                     NLBL_MGMT_C_VERSION);
+       data = genlmsg_put_reply(ans_skb, info, &netlbl_mgmt_gnl_family,
+                                0, NLBL_MGMT_C_VERSION);
        if (data == NULL)
                goto version_failure;
 
@@ -501,7 +502,7 @@ static int netlbl_mgmt_version(struct sk_buff *skb, struct genl_info *info)
 
        genlmsg_end(ans_skb, data);
 
-       ret_val = genlmsg_unicast(ans_skb, info->snd_pid);
+       ret_val = genlmsg_reply(ans_skb, info);
        if (ret_val != 0)
                goto version_failure;
        return 0;
@@ -516,68 +517,63 @@ version_failure:
  * NetLabel Generic NETLINK Command Definitions
  */
 
-static struct genl_ops netlbl_mgmt_genl_c_add = {
+static struct genl_ops netlbl_mgmt_genl_ops[] = {
+       {
        .cmd = NLBL_MGMT_C_ADD,
        .flags = GENL_ADMIN_PERM,
        .policy = netlbl_mgmt_genl_policy,
        .doit = netlbl_mgmt_add,
        .dumpit = NULL,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_remove = {
+       },
+       {
        .cmd = NLBL_MGMT_C_REMOVE,
        .flags = GENL_ADMIN_PERM,
        .policy = netlbl_mgmt_genl_policy,
        .doit = netlbl_mgmt_remove,
        .dumpit = NULL,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_listall = {
+       },
+       {
        .cmd = NLBL_MGMT_C_LISTALL,
        .flags = 0,
        .policy = netlbl_mgmt_genl_policy,
        .doit = NULL,
        .dumpit = netlbl_mgmt_listall,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_adddef = {
+       },
+       {
        .cmd = NLBL_MGMT_C_ADDDEF,
        .flags = GENL_ADMIN_PERM,
        .policy = netlbl_mgmt_genl_policy,
        .doit = netlbl_mgmt_adddef,
        .dumpit = NULL,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_removedef = {
+       },
+       {
        .cmd = NLBL_MGMT_C_REMOVEDEF,
        .flags = GENL_ADMIN_PERM,
        .policy = netlbl_mgmt_genl_policy,
        .doit = netlbl_mgmt_removedef,
        .dumpit = NULL,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_listdef = {
+       },
+       {
        .cmd = NLBL_MGMT_C_LISTDEF,
        .flags = 0,
        .policy = netlbl_mgmt_genl_policy,
        .doit = netlbl_mgmt_listdef,
        .dumpit = NULL,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_protocols = {
+       },
+       {
        .cmd = NLBL_MGMT_C_PROTOCOLS,
        .flags = 0,
        .policy = netlbl_mgmt_genl_policy,
        .doit = NULL,
        .dumpit = netlbl_mgmt_protocols,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_version = {
+       },
+       {
        .cmd = NLBL_MGMT_C_VERSION,
        .flags = 0,
        .policy = netlbl_mgmt_genl_policy,
        .doit = netlbl_mgmt_version,
        .dumpit = NULL,
+       },
 };
 
 /*
@@ -592,46 +588,20 @@ static struct genl_ops netlbl_mgmt_genl_c_version = {
  * mechanism.  Returns zero on success, negative values on failure.
  *
  */
-int netlbl_mgmt_genl_init(void)
+int __init netlbl_mgmt_genl_init(void)
 {
-       int ret_val;
+       int ret_val, i;
 
        ret_val = genl_register_family(&netlbl_mgmt_gnl_family);
        if (ret_val != 0)
                return ret_val;
 
-       ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
-                                   &netlbl_mgmt_genl_c_add);
-       if (ret_val != 0)
-               return ret_val;
-       ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
-                                   &netlbl_mgmt_genl_c_remove);
-       if (ret_val != 0)
-               return ret_val;
-       ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
-                                   &netlbl_mgmt_genl_c_listall);
-       if (ret_val != 0)
-               return ret_val;
-       ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
-                                   &netlbl_mgmt_genl_c_adddef);
-       if (ret_val != 0)
-               return ret_val;
-       ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
-                                   &netlbl_mgmt_genl_c_removedef);
-       if (ret_val != 0)
-               return ret_val;
-       ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
-                                   &netlbl_mgmt_genl_c_listdef);
-       if (ret_val != 0)
-               return ret_val;
-       ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
-                                   &netlbl_mgmt_genl_c_protocols);
-       if (ret_val != 0)
-               return ret_val;
-       ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
-                                   &netlbl_mgmt_genl_c_version);
-       if (ret_val != 0)
-               return ret_val;
+       for (i = 0; i < ARRAY_SIZE(netlbl_mgmt_genl_ops); i++) {
+               ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
+                               &netlbl_mgmt_genl_ops[i]);
+               if (ret_val != 0)
+                       return ret_val;
+       }
 
        return 0;
 }