summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2010-06-04 07:28:19 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2010-06-17 20:47:39 +0200
commitc8f69207e6d5fb654814833676f5f786084a8576 (patch)
tree229f8e227af42111adc988015112707330f530d8
parentf3146e2631f23c80e9ce43cbff33b294cab9f535 (diff)
downloadkernel-crypto-c8f69207e6d5fb654814833676f5f786084a8576.tar.gz
kernel-crypto-c8f69207e6d5fb654814833676f5f786084a8576.tar.xz
kernel-crypto-c8f69207e6d5fb654814833676f5f786084a8576.zip
Some updates in the server approach (not working yet).
-rw-r--r--cryptodev_main.c14
-rw-r--r--examples/new.c157
-rw-r--r--ncr-storage-low.c165
-rw-r--r--ncr-storage-low.h8
-rw-r--r--ncr-storage.c9
-rw-r--r--ncr-storage.h4
-rw-r--r--ncr_int.h2
-rw-r--r--userspace/ncr-server/Makefile4
-rw-r--r--userspace/ncr-server/ncr-server.c81
9 files changed, 360 insertions, 84 deletions
diff --git a/cryptodev_main.c b/cryptodev_main.c
index 460e3d3df1e..58ae45b647e 100644
--- a/cryptodev_main.c
+++ b/cryptodev_main.c
@@ -510,7 +510,6 @@ cryptodev_open(struct inode *inode, struct file *filp)
init_MUTEX(&pcr->fcrypt.sem);
INIT_LIST_HEAD(&pcr->fcrypt.list);
-
pcr->ncr = ncr_init_lists();
if (pcr->ncr == NULL) {
kfree(pcr);
@@ -730,9 +729,17 @@ cryptodev_register(void)
ncr_limits_init();
+ rc = ncr_gnl_init();
+ if (rc < 0) {
+ ncr_limits_deinit();
+ return rc;
+ }
+
rc = misc_register (&cryptodev);
if (unlikely(rc)) {
- printk(KERN_ERR PFX "registeration of /dev/crypto failed\n");
+ ncr_gnl_deinit();
+ ncr_limits_deinit();
+ printk(KERN_ERR PFX "registration of /dev/crypto failed\n");
return rc;
}
@@ -742,8 +749,9 @@ cryptodev_register(void)
static void
cryptodev_deregister(void)
{
- ncr_limits_deinit();
misc_deregister(&cryptodev);
+ ncr_gnl_deinit();
+ ncr_limits_deinit();
}
/* ====== Module init/exit ====== */
diff --git a/examples/new.c b/examples/new.c
index 32e17dcfc51..cdc3baa5d70 100644
--- a/examples/new.c
+++ b/examples/new.c
@@ -10,6 +10,8 @@
#include <fcntl.h>
#include <time.h>
#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include "../ncr.h"
#include <stdlib.h>
@@ -376,6 +378,158 @@ static int test_ncr_data(int cfd)
return 0;
}
+static int
+test_ncr_store_key(int cfd)
+{
+ struct ncr_data_init_st dinit;
+ struct ncr_key_generate_st kgen;
+ ncr_key_t key, key2;
+ struct ncr_key_data_st keydata;
+ struct ncr_data_st kdata;
+ uint8_t data[KEY_DATA_SIZE];
+ uint8_t data_bak[KEY_DATA_SIZE];
+ struct ncr_storage_st kstore;
+
+ fprintf(stdout, "Tests on Key Storage:\n");
+
+ /* test 1: generate a key in kernel and store it.
+ * The try to load it.
+ */
+ fprintf(stdout, "\tKey storage/retrieval...\n");
+
+ /* initialize data */
+ dinit.max_object_size = KEY_DATA_SIZE;
+ dinit.flags = NCR_DATA_FLAG_EXPORTABLE;
+ dinit.initial_data = NULL;
+ dinit.initial_data_size = 0;
+
+ if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_DATA_INIT)");
+ return 1;
+ }
+
+ if (ioctl(cfd, NCRIO_KEY_INIT, &key)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_KEY_INIT)");
+ return 1;
+ }
+
+ if (ioctl(cfd, NCRIO_KEY_INIT, &key2)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_KEY_INIT)");
+ return 1;
+ }
+
+ kgen.desc = key;
+ kgen.params.algorithm = NCR_ALG_AES_CBC;
+ kgen.params.keyflags = NCR_KEY_FLAG_EXPORTABLE;
+ kgen.params.params.secret.bits = 128; /* 16 bytes */
+
+ if (ioctl(cfd, NCRIO_KEY_GENERATE, &kgen)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_KEY_IMPORT)");
+ return 1;
+ }
+
+
+ memset(&keydata, 0, sizeof(keydata));
+ keydata.key = key;
+ keydata.data = dinit.desc;
+
+ if (ioctl(cfd, NCRIO_KEY_EXPORT, &keydata)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_KEY_IMPORT)");
+ return 1;
+ }
+
+ /* now read data */
+ memset(data, 0, sizeof(data));
+
+ kdata.desc = dinit.desc;
+ kdata.data = data_bak;
+ kdata.data_size = sizeof(data_bak);
+ kdata.append_flag = 0;
+
+ if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_DATA_GET)");
+ return 1;
+ }
+
+ /* ok now key stands in data[]. Store it. */
+
+ kstore.key = key;
+ strcpy(kstore.label, "testkey");
+ kstore.mode = S_IRWXU;
+
+ if (ioctl(cfd, NCRIO_STORAGE_STORE, &kstore)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_STORAGE_STORE)");
+ return 1;
+ }
+
+ kstore.key = key2;
+
+ if (ioctl(cfd, NCRIO_STORAGE_LOAD, &kstore)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_STORAGE_LOAD)");
+ return 1;
+ }
+
+ /* export it */
+ memset(&keydata, 0, sizeof(keydata));
+ keydata.key = key2;
+ keydata.data = dinit.desc;
+
+ if (ioctl(cfd, NCRIO_KEY_EXPORT, &keydata)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_KEY_IMPORT)");
+ return 1;
+ }
+
+ /* now read data */
+ memset(data, 0, sizeof(data));
+
+ kdata.desc = dinit.desc;
+ kdata.data = data;
+ kdata.data_size = sizeof(data);
+ kdata.append_flag = 0;
+
+ if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_DATA_GET)");
+ return 1;
+ }
+
+ if (memcmp(data, data_bak, kdata.data_size)!=0) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ fprintf(stderr, "Loaded data do not match stored\n");
+ return 1;
+ }
+
+ if (ioctl(cfd, NCRIO_KEY_DEINIT, &key)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_KEY_DEINIT)");
+ return 1;
+ }
+
+ if (ioctl(cfd, NCRIO_KEY_DEINIT, &key2)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_KEY_DEINIT)");
+ return 1;
+ }
+
+ if (ioctl(cfd, NCRIO_DATA_DEINIT, &dinit.desc)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_DATA_DEINIT)");
+ return 1;
+ }
+
+
+ return 0;
+}
+
int
main()
{
@@ -410,6 +564,9 @@ main()
if (test_ncr_key(fd))
return 1;
+ if (test_ncr_store_key(fd))
+ return 1;
+
/* Close the original descriptor */
if (close(fd)) {
perror("close(fd)");
diff --git a/ncr-storage-low.c b/ncr-storage-low.c
index 418bc8ff969..489aa2ecfe4 100644
--- a/ncr-storage-low.c
+++ b/ncr-storage-low.c
@@ -60,6 +60,7 @@ struct event_item_st* item;
item->id = id;
item->reply = NULL;
item->reply_size = 0;
+ item->ireply = -1;
init_completion(&item->completed);
down(&event_list.sem);
@@ -73,10 +74,8 @@ static int event_wait(uint32_t id)
{
struct event_item_st* item;
struct completion* completed = NULL;
-int ret = 0;
down(&event_list.sem);
-
list_for_each_entry(item, &event_list.list, list) {
if (id == item->id) {
completed = &item->completed;
@@ -84,10 +83,13 @@ int ret = 0;
}
}
up(&event_list.sem);
+
if (completed) {
- ret = wait_for_completion_interruptible(completed);
+ return wait_for_completion_interruptible(completed);
+ } else {
+ err();
+ return -EIO;
}
- return 0;
}
@@ -203,23 +205,73 @@ struct event_item_st* item, *tmp;
static struct nla_policy ncr_genl_policy[ATTR_MAX + 1] = {
[ATTR_STRUCT_LOAD] = { .type = NLA_BINARY },
[ATTR_STRUCT_LOADED] = { .type = NLA_BINARY },
- [ATTR_STORE_ACK] = { .type = NLA_BINARY },
+ [ATTR_STORE_U8] = { .type = NLA_BINARY },
[ATTR_STRUCT_STORE] = { .type = NLA_BINARY },
};
static atomic_t ncr_event_sr;
static uint32_t listener_pid = -1;
-#define VERSION_NR 1
/* family definition */
static struct genl_family ncr_gnl_family = {
.id = GENL_ID_GENERATE, //genetlink should generate an id
.hdrsize = 0,
.name = NCR_NL_STORAGE_NAME, //the name of this family, used by userspace application
- .version = VERSION_NR, //version number
+ .version = NCR_NL_STORAGE_VERSION, //version number
.maxattr = ATTR_MAX,
};
+/* an echo command, receives a message, prints it and sends another message back */
+static void _ncr_nl_close(void)
+{
+ struct sk_buff *skb;
+ int ret;
+ void *msg_head;
+ uint32_t id;
+
+ if (listener_pid == -1) {
+ err();
+ return;
+ }
+
+ skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+ if (skb == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ id = atomic_add_return(1, &ncr_event_sr);
+ msg_head = genlmsg_put(skb, 0, id, &ncr_gnl_family, 0, CMD_CLOSE);
+ if (msg_head == NULL) {
+ err();
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = nla_put_u8(skb, ATTR_STORE_U8, 1);
+ if (ret != 0) {
+ err();
+ goto out;
+ }
+
+ /* finalize the message */
+ genlmsg_end(skb, msg_head);
+
+ /* send the message back */
+ ret = genlmsg_unicast(skb, listener_pid);
+ if (ret != 0) {
+ err();
+ goto out;
+ }
+
+ return;
+
+out:
+ nlmsg_free(skb);
+ printk("an error occured in ncr_gnl_store\n");
+
+ return;
+}
/* an echo command, receives a message, prints it and sends another message back */
int _ncr_store(const struct storage_item_st * tostore)
@@ -236,7 +288,7 @@ int _ncr_store(const struct storage_item_st * tostore)
err();
return -EIO;
}
-
+
/* send a message back*/
/* allocate some memory, since the size is not yet known use NLMSG_GOODSIZE*/
size = nla_total_size(sizeof(struct storage_item_st)) +
@@ -248,7 +300,7 @@ int _ncr_store(const struct storage_item_st * tostore)
goto out;
}
- id = atomic_long_inc_return(&ncr_event_sr);
+ id = atomic_add_return(1, &ncr_event_sr);
msg_head = genlmsg_put(skb, 0, id,
&ncr_gnl_family, 0, CMD_STORE);
if (msg_head == NULL) {
@@ -278,6 +330,12 @@ int _ncr_store(const struct storage_item_st * tostore)
/* finalize the message */
genlmsg_end(skb, msg_head);
+ ret = event_add(id);
+ if (ret < 0) {
+ err();
+ goto out;
+ }
+
/* send the message back */
ret = genlmsg_unicast(skb, listener_pid);
if (ret != 0)
@@ -286,10 +344,13 @@ int _ncr_store(const struct storage_item_st * tostore)
/* wait for an acknowledgment */
ret = event_wait(id);
if (ret) {
- goto out;
+ err();
+ printk(KERN_DEBUG"Error waiting for id %u\n", id);
+ event_remove(id);
+ return ret;
}
- reply = event_get_idata(id, &reply_size);
+ reply = event_get_idata(id);
if (reply == (uint32_t)-1)
BUG();
@@ -317,7 +378,7 @@ int _ncr_load(struct storage_item_st * toload)
struct sk_buff *skb;
int ret;
void *msg_head;
- size_t size, reply_size;
+ size_t reply_size=0, size;
struct nlattr *attr;
void* msg, *reply;
struct ncr_gnl_load_cmd_st cmd;
@@ -339,7 +400,7 @@ int _ncr_load(struct storage_item_st * toload)
goto out;
}
- id = atomic_long_inc_return(&ncr_event_sr);
+ id = atomic_add_return(1, &ncr_event_sr);
msg_head = genlmsg_put(skb, 0, id,
&ncr_gnl_family, 0, CMD_LOAD);
if (msg_head == NULL) {
@@ -386,7 +447,10 @@ int _ncr_load(struct storage_item_st * toload)
/* wait for an answer */
ret = event_wait(id);
if (ret) {
- goto out;
+ err();
+ printk(KERN_DEBUG"Error waiting for id %u\n", id);
+ event_remove(id);
+ return ret;
}
reply = event_get_data(id, &reply_size);
@@ -413,6 +477,8 @@ int ncr_gnl_listen(struct sk_buff *skb, struct genl_info *info)
return -EIO;
listener_pid = info->snd_pid;
+ atomic_set(&ncr_event_sr, info->snd_seq+1);
+ printk(KERN_DEBUG"Setting listener pid to %d!\n", (int)listener_pid);
return 0;
}
@@ -421,33 +487,32 @@ int ncr_gnl_listen(struct sk_buff *skb, struct genl_info *info)
/* with this command the userspace server registers */
int ncr_gnl_store_ack(struct sk_buff *skb, struct genl_info *info)
{
- uint8_t * data, *event_reply;
+ uint8_t * data;
size_t len;
- struct ncr_gnl_store_ack_st reply;
+ struct ncr_gnl_store_ack_st *reply;
struct nlattr *na;
if (info == NULL)
return -EIO;
+ printk("Received store ack!\n");
/*for each attribute there is an index in info->attrs which points to a nlattr structure
*in this structure the data is given
*/
- na = info->attrs[ATTR_STORE_ACK];
+ na = info->attrs[ATTR_STORE_U8];
if (na) {
len = nla_len(na);
data = (void *)nla_data(na);
if (data == NULL || len != sizeof(struct ncr_gnl_store_ack_st))
printk(KERN_DEBUG"error while receiving data\n");
else {
-
- memcpy( &reply, data, sizeof(reply));
-
- event_set_idata(reply.id, (uint32_t)reply.reply[0]);
+ reply = (void*)data;
+ event_set_idata(reply->id, (uint32_t)reply->reply);
- event_complete(reply.id);
+ event_complete(reply->id);
}
} else
- printk(KERN_DEBUG"no info->attrs %i\n", ATTR_STORE_ACK);
+ printk(KERN_DEBUG"no info->attrs %i\n", ATTR_STORE_U8);
return 0;
}
@@ -457,7 +522,7 @@ int ncr_gnl_loaded_data(struct sk_buff *skb, struct genl_info *info)
{
uint8_t * data, *event_reply;
size_t len;
- struct ncr_gnl_loaded_st reply;
+ struct ncr_gnl_loaded_st *reply;
struct nlattr *na;
if (info == NULL)
@@ -473,14 +538,13 @@ int ncr_gnl_loaded_data(struct sk_buff *skb, struct genl_info *info)
if (data == NULL || len != sizeof(struct ncr_gnl_loaded_st))
printk(KERN_DEBUG"error while receiving data\n");
else {
-
- memcpy( &reply, data, sizeof(reply));
- event_reply = kmalloc(sizeof(reply.storage), GFP_KERNEL);
+ reply = (void*)data;
+ event_reply = kmalloc(sizeof(reply->storage), GFP_KERNEL);
if (event_reply != NULL) {
- memcpy(event_reply, &reply.storage, sizeof(reply.storage));
- event_set_data(reply.id, event_reply, sizeof(reply.storage));
+ memcpy(event_reply, &reply->storage, sizeof(reply->storage));
+ event_set_data(reply->id, event_reply, sizeof(reply->storage));
}
- event_complete(reply.id);
+ event_complete(reply->id);
}
} else
printk(KERN_DEBUG"no info->attrs %i\n", ATTR_STRUCT_LOADED);
@@ -519,35 +583,38 @@ struct genl_ops ncr_gnl_ops_store_ack = {
int ncr_gnl_init(void)
{
int rc;
- printk("INIT GENERIC NETLINK EXEMPLE MODULE\n");
+
+ printk(KERN_NOTICE"cryptodev: Initializing netlink subsystem.\n");
init_MUTEX(&event_list.sem);
INIT_LIST_HEAD(&event_list.list);
- atomic_set(&ncr_event_sr, 0);
+ atomic_set(&ncr_event_sr, 1);
- /*register new family*/
+ /*register new family*/
rc = genl_register_family(&ncr_gnl_family);
- if (rc != 0)
+ if (rc != 0) {
+ err();
goto failure;
- /*register functions (commands) of the new family*/
+ }
+ /*register functions (commands) of the new family*/
rc = genl_register_ops(&ncr_gnl_family, &ncr_gnl_ops_listen);
if (rc != 0) {
- printk("register ops: %i\n",rc);
+ err();
genl_unregister_family(&ncr_gnl_family);
goto failure;
}
rc = genl_register_ops(&ncr_gnl_family, &ncr_gnl_ops_store_ack);
if (rc != 0) {
- printk("register ops: %i\n",rc);
+ err();
genl_unregister_family(&ncr_gnl_family);
goto failure;
}
rc = genl_register_ops(&ncr_gnl_family, &ncr_gnl_ops_load);
if (rc != 0) {
- printk("register ops: %i\n",rc);
+ err();
genl_unregister_family(&ncr_gnl_family);
goto failure;
}
@@ -555,7 +622,7 @@ int ncr_gnl_init(void)
return 0;
failure:
- printk("an error occured while inserting the generic netlink example module\n");
+ printk(KERN_ERR"an error occured while loading the cryptodev netlink subsystem\n");
return rc;
}
@@ -563,15 +630,8 @@ void ncr_gnl_deinit(void)
{
int ret;
struct event_item_st *item, *tmp;
- printk("EXIT GENERIC NETLINK EXEMPLE MODULE\n");
- /* deinitialize the event list */
- down(&event_list.sem);
- list_for_each_entry_safe(item, tmp, &event_list.list, list) {
- list_del(&item->list);
- kfree(item);
- }
- up(&event_list.sem);
+ _ncr_nl_close();
ret = genl_unregister_ops(&ncr_gnl_family, &ncr_gnl_ops_store_ack);
if(ret != 0) {
@@ -596,4 +656,15 @@ void ncr_gnl_deinit(void)
if(ret !=0) {
printk("unregister family %i\n",ret);
}
+
+ /* deinitialize the event list */
+ down(&event_list.sem);
+ list_for_each_entry_safe(item, tmp, &event_list.list, list) {
+ list_del(&item->list);
+ if (item->reply)
+ kfree(item->reply);
+ kfree(item);
+ }
+ up(&event_list.sem);
+
}
diff --git a/ncr-storage-low.h b/ncr-storage-low.h
index 814b0df2893..080a161cf11 100644
--- a/ncr-storage-low.h
+++ b/ncr-storage-low.h
@@ -1,7 +1,7 @@
#ifndef _STORAGE_LOW
#define _STORAGE_LOW
-#include <ncr.h>
+#include "ncr.h"
#define NCR_NL_STORAGE_NAME "KEY_STORAGE"
@@ -16,6 +16,7 @@ enum {
CMD_LOAD, /* sent by kernel */
CMD_STORE_ACK, /* sent by server */
CMD_LOADED_DATA, /* sent by server */
+ CMD_CLOSE, /* sent by kernel */
__CMD_MAX,
};
#define CMD_MAX (__CMD_MAX - 1)
@@ -29,7 +30,7 @@ enum {
ATTR_STRUCT_LOAD,
ATTR_STRUCT_LOADED,
ATTR_STRUCT_STORE,
- ATTR_STORE_ACK, /* u8*/
+ ATTR_STORE_U8, /* u8*/
__ATTR_MAX,
};
#define ATTR_MAX (__ATTR_MAX - 1)
@@ -43,9 +44,10 @@ struct storage_item_st {
uint32_t owner;
uint32_t group;
mode_t mode;
-
+
uint16_t algorithm;
uint8_t type;
+ uint32_t flags;
uint8_t key_id[MAX_KEY_ID_SIZE];
uint8_t key_id_size;
diff --git a/ncr-storage.c b/ncr-storage.c
index 15df0debc1c..d19a44fb98f 100644
--- a/ncr-storage.c
+++ b/ncr-storage.c
@@ -25,6 +25,8 @@
#include <asm/uaccess.h>
#include <asm/ioctl.h>
#include <linux/scatterlist.h>
+#include <linux/file.h>
+#include <linux/cred.h>
#include <linux/version.h>
#include "ncr.h"
#include "ncr_int.h"
@@ -39,12 +41,13 @@ int _ncr_key_to_store(const struct key_item_st *key, const char* label,
uid_t uid = key->filp->f_uid;
gid_t gid = key->filp->f_gid;
#else
- gid_t gid = key->filp->f_cred->fsgid;
+ uid_t uid = key->filp->f_cred->fsuid;
gid_t gid = key->filp->f_cred->fsgid;
#endif
/* copy metadata first */
memcpy(output->key_id, key->key_id, sizeof(output->key_id));
output->key_id_size = key->key_id_size;
+ output->flags = key->flags;
output->algorithm = key->algorithm;
output->type = key->type;
@@ -79,6 +82,7 @@ int _ncr_store_to_key(const struct storage_item_st* raw, struct key_item_st *key
key->algorithm = raw->algorithm;
key->type = raw->type;
+ key->flags = raw->flags;
switch(key->type) {
case NCR_KEY_TYPE_SECRET:
@@ -120,6 +124,7 @@ int ncr_storage_store(struct list_sem_st* key_lst, void __user* arg)
ret = _ncr_store(&tostore);
if (ret < 0) {
+ printk("cryptodev: Cannot store. Is ncr-server running?\n");
err();
goto fail;
}
@@ -154,7 +159,7 @@ int ncr_storage_load(struct list_sem_st* key_lst, void __user* arg)
uid = key->filp->f_uid;
gid = key->filp->f_gid;
#else
- gid = key->filp->f_cred->fsgid;
+ uid = key->filp->f_cred->fsuid;
gid = key->filp->f_cred->fsgid;
#endif
diff --git a/ncr-storage.h b/ncr-storage.h
index 9384b6ef6f5..0f15f726f9f 100644
--- a/ncr-storage.h
+++ b/ncr-storage.h
@@ -18,4 +18,8 @@ int ncr_storage_traverse_deinit(struct list_sem_st* tr_lst, void __user* arg);
int _ncr_store(const struct storage_item_st * tostore);
int _ncr_load(struct storage_item_st * loaded);
+/* Netlink subsystem; */
+void ncr_gnl_deinit(void);
+int ncr_gnl_init(void);
+
#endif /* NCR_STORAGE_H */
diff --git a/ncr_int.h b/ncr_int.h
index cf265072fa4..22fc7c53f77 100644
--- a/ncr_int.h
+++ b/ncr_int.h
@@ -4,7 +4,7 @@
#include "ncr.h"
#include <asm/atomic.h>
-#define err() printk(KERN_DEBUG"ncr: %s: %d\n", __func__, __LINE__)
+#define err() printk(KERN_DEBUG"ncr: %s: %s: %d\n", __FILE__, __func__, __LINE__)
struct data_item_st {
struct list_head list;
diff --git a/userspace/ncr-server/Makefile b/userspace/ncr-server/Makefile
index ee46dd6ae46..79e380d1803 100644
--- a/userspace/ncr-server/Makefile
+++ b/userspace/ncr-server/Makefile
@@ -1,7 +1,7 @@
all: ncr-server
-CFLAGS=-O2 -Wall -g -I.. -I.
+CFLAGS=-O2 -Wall -g -I.. -I. -I../../
CC=gcc
ncr-server: ncr-server.c ncr-server.h
- $(CC) $(CFLAGS) ncr-server.c -o ncr-server
+ $(CC) $(CFLAGS) ncr-server.c -o ncr-server -lnl
diff --git a/userspace/ncr-server/ncr-server.c b/userspace/ncr-server/ncr-server.c
index 3b3c72ad145..bbcf859e9c5 100644
--- a/userspace/ncr-server/ncr-server.c
+++ b/userspace/ncr-server/ncr-server.c
@@ -7,9 +7,9 @@
#include <netlink/genl/ctrl.h>
#include "../ncr-storage-low.h"
#include "ncr-server.h"
-#include <list.h>
+#include "list.h"
-static int _notify_listening(struct nl_sock * sock);
+static int _notify_listening(int family, struct nl_handle * sock);
static struct nla_policy def_policy[ATTR_MAX+1] =
{
@@ -19,18 +19,20 @@ static struct nla_policy def_policy[ATTR_MAX+1] =
.minlen = sizeof(struct ncr_gnl_load_cmd_st) },
};
-static struct actions {
- list_head list;
+struct todo_actions {
+ struct list_head list;
int cmd; /* CMD_* */
union {
struct storage_item_st tostore;
struct ncr_gnl_load_cmd_st toload;
} data;
-} todo;
+};
+
+static struct todo_actions todo;
static int add_store_cmd(struct storage_item_st* tostore)
{
- struct actions* item;
+ struct todo_actions* item;
item = malloc(sizeof(*item));
if (item == NULL) {
@@ -38,15 +40,15 @@ static int add_store_cmd(struct storage_item_st* tostore)
return -ERR_MEM;
}
item->cmd = CMD_STORE;
- memcpy(item->data.tostore, tostore, sizeof(item->data.tostore));
+ memcpy(&item->data.tostore, tostore, sizeof(item->data.tostore));
- list_add(item, &todo.list);
+ list_add(&item->list, &todo.list);
return 0;
}
static int add_load_cmd(struct ncr_gnl_load_cmd_st* toload)
{
- struct actions* item;
+ struct todo_actions* item;
item = malloc(sizeof(*item));
if (item == NULL) {
@@ -54,9 +56,9 @@ static int add_load_cmd(struct ncr_gnl_load_cmd_st* toload)
return -ERR_MEM;
}
item->cmd = CMD_LOAD;
- memcpy(item->data.toload, toload, sizeof(item->data.toload));
+ memcpy(&item->data.toload, toload, sizeof(item->data.toload));
- list_add(item, &todo.list);
+ list_add(&item->list, &todo.list);
return 0;
}
@@ -65,37 +67,55 @@ static int msg_cb(struct nl_msg *msg, void *arg)
struct nlmsghdr *nlh = nlmsg_hdr(msg);
struct nlattr *attrs[ATTR_MAX+1];
+fprintf(stderr, "Received message: ");
// Validate message and parse attributes
genlmsg_parse(nlh, 0, attrs, ATTR_MAX, def_policy);
if (attrs[ATTR_STRUCT_STORE]) {
- struct storage_item_st *item = nla_get(attrs[ATTR_STRUCT_STORE]);
+ struct nl_data* data = nla_get_data(attrs[ATTR_STRUCT_STORE]);
+ struct storage_item_st *item = nl_data_get(data);
+
+fprintf(stderr, "Store!\n");
+
+ if (nl_data_get_size(data) != sizeof(struct storage_item_st)) {
+ err();
+ fprintf(stderr, "Received incorrect structure!\n");
+ return -1;
+ }
fprintf(stderr, "asked to store: %s\n", item->label);
add_store_cmd(item);
}
if (attrs[ATTR_STRUCT_LOAD]) {
- struct ncr_gnl_load_cmd_st *load = nla_get(attrs[ATTR_STRUCT_LOAD]);
+ struct nl_data* data = nla_get_data(attrs[ATTR_STRUCT_STORE]);
+ struct ncr_gnl_load_cmd_st *load = nl_data_get(data);
+
+fprintf(stderr, "Load!\n");
+ if (nl_data_get_size(data) != sizeof(struct ncr_gnl_load_cmd_st)) {
+ err();
+ fprintf(stderr, "Received incorrect structure!\n");
+ return -1;
+ }
fprintf(stderr, "asked to load: %s\n", load->label);
- add_load_cmd(item);
+ add_load_cmd(load);
}
-
+fprintf(stderr, "\n");
return NL_STOP;
}
int main()
{
-struct nl_sock *sock;
-int ret;
+struct nl_handle *sock;
+int ret, family;
memset(&todo, 0, sizeof(todo));
- LIST_HEAD_INIT(&todo.list);
+ INIT_LIST_HEAD(&todo.list);
// Allocate a new netlink socket
- sock = nl_socket_alloc();
+ sock = nl_handle_alloc();
if (sock == NULL) {
err();
return ERR_CONNECT;
@@ -122,14 +142,16 @@ int ret;
exit(1);
}
- ret = _notify_listening(sock);
+ ret = _notify_listening(family, sock);
if (ret < 0) {
fprintf(stderr, "Could not notify kernel subsystem.\n");
exit(1);
}
+ fprintf(stderr, "Notified kernel for being a listener...\n");
// Wait for the answer and receive it
do {
+ fprintf(stderr, "Waiting for message...\n");
ret = nl_recvmsgs_default(sock);
/* we have to consume the todo list */
@@ -140,12 +162,14 @@ int ret;
} while (ret == 0);
fprintf(stderr, "received: %d\n", ret);
+ return 0;
}
-static int _notify_listening(struct nl_sock * sock)
+static int _notify_listening(int family, struct nl_handle * sock)
{
struct nl_msg *msg;
-int family, ret;
+void * hdr;
+int ret;
// Construct a generic netlink by allocating a new message, fill in
// the header and append a simple integer attribute.
@@ -155,8 +179,13 @@ int family, ret;
return ERR_MEM;
}
- genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_REQUEST,
+ hdr = genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_REQUEST,
CMD_LISTENING, NCR_NL_STORAGE_VERSION);
+
+ if (hdr == NULL) {
+ err();
+ return ERR_SEND;
+ }
// Send message over netlink socket
ret = nl_send_auto_complete(sock, msg);
@@ -171,10 +200,10 @@ int family, ret;
}
-static int send_store_ack(struct nl_sock * sock, uint8_t val)
+static int send_store_ack(int family, struct nl_handle * sock, uint8_t val)
{
struct nl_msg *msg;
-int family, ret;
+int ret;
// Construct a generic netlink by allocating a new message, fill in
// the header and append a simple integer attribute.
@@ -187,7 +216,7 @@ int family, ret;
genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_REQUEST,
CMD_STORE_ACK, NCR_NL_STORAGE_VERSION);
- ret = nla_put_u8(msg, ATTR_STORE_ACK, val);
+ ret = nla_put_u8(msg, ATTR_STORE_U8, val);
if (ret < 0) {
err();
ret = ERR_SEND;