+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
++ * published by the Free Software Foundation.
+ */
+
+#if 0
+ * - in order to "deal with" backward compatibility, renamed to ipset
+ */
+
-+/*
-+ * Used so that the kernel module and ipset-binary can match their versions
++/*
++ * Used so that the kernel module and ipset-binary can match their versions
+ */
+#define IP_SET_PROTOCOL_VERSION 2
+
+ *
+ * The representation works in HOST byte order, because most set types
+ * will perform arithmetic operations and compare operations.
-+ *
++ *
+ * For now the type is an uint32_t.
+ *
+ * Make sure to ONLY use the functions when translating and parsing
+ * 200-299: list, save, restore
+ */
+
-+/* Single shot operations:
-+ * version, create, destroy, flush, rename and swap
++/* Single shot operations:
++ * version, create, destroy, flush, rename and swap
+ *
+ * Sets are identified by name.
+ */
+ unsigned version;
+};
+
-+/* Double shots operations:
++/* Double shots operations:
+ * add, del, test, bind and unbind.
+ *
+ * First we query the kernel to get the index and type of the target set,
+};
+
+#define IP_SET_OP_UNBIND_SET 0x00000105 /* Unbind an IP from a set */
-+/* Uses ip_set_req_bind, with type speficic addage
++/* Uses ip_set_req_bind, with type speficic addage
+ * index = 0 means unbinding for all sets */
+
+#define IP_SET_OP_TEST_BIND_SET 0x00000106 /* Test binding an IP to a set */
+#define IP_SET_OP_LIST 0x00000203
+struct ip_set_req_list {
+ IP_SET_REQ_BYINDEX;
-+ /* sets number of struct ip_set_list in reply */
++ /* sets number of struct ip_set_list in reply */
+};
+
+struct ip_set_list {
+/* The restore operation */
+#define IP_SET_OP_RESTORE 0x00000205
+/* Uses ip_set_req_setnames followed by ip_set_restore structures
-+ * plus a marker ip_set_restore, followed by ip_set_hash_save
++ * plus a marker ip_set_restore, followed by ip_set_hash_save
+ * structures.
+ */
+struct ip_set_restore {
+ * return 0 if not in set, 1 if in set.
+ */
+ int (*testip_kernel) (struct ip_set *set,
-+ const struct sk_buff * skb,
++ const struct sk_buff * skb,
+ ip_set_ip_t *ip,
+ const u_int32_t *flags,
+ unsigned char index);
+ * and -ERANGE if the address lies outside the set bounds.
+ * If the address was not already in the set, 0 is returned.
+ */
-+ int (*addip) (struct ip_set *set,
++ int (*addip) (struct ip_set *set,
+ const void *data, size_t size,
+ ip_set_ip_t *ip);
+
+ * If the address was not already in the set, 0 is returned.
+ */
+ int (*addip_kernel) (struct ip_set *set,
-+ const struct sk_buff * skb,
++ const struct sk_buff * skb,
+ ip_set_ip_t *ip,
+ const u_int32_t *flags,
+ unsigned char index);
+ * and -ERANGE if the address lies outside the set bounds.
+ * If the address really was in the set, 0 is returned.
+ */
-+ int (*delip) (struct ip_set *set,
++ int (*delip) (struct ip_set *set,
+ const void *data, size_t size,
+ ip_set_ip_t *ip);
+
+ * If the address really was in the set, 0 is returned.
+ */
+ int (*delip_kernel) (struct ip_set *set,
-+ const struct sk_buff * skb,
++ const struct sk_buff * skb,
+ ip_set_ip_t *ip,
+ const u_int32_t *flags,
+ unsigned char index);
+ /* Listing: Get the header
+ *
+ * Fill in the information in "data".
-+ * This function is always run after list_header_size() under a
-+ * writelock on the set. Therefor is the length of "data" always
-+ * correct.
++ * This function is always run after list_header_size() under a
++ * writelock on the set. Therefor is the length of "data" always
++ * correct.
+ */
-+ void (*list_header) (const struct ip_set *set,
++ void (*list_header) (const struct ip_set *set,
+ void *data);
+
+ /* Listing: Get the size for the set members
+ /* Listing: Get the set members
+ *
+ * Fill in the information in "data".
-+ * This function is always run after list_member_size() under a
-+ * writelock on the set. Therefor is the length of "data" always
-+ * correct.
++ * This function is always run after list_member_size() under a
++ * writelock on the set. Therefor is the length of "data" always
++ * correct.
+ */
+ void (*list_members) (const struct ip_set *set,
+ void *data);
+{
+ unsigned int bits = 32;
+ ip_set_ip_t maskaddr;
-+
++
+ if (mask == 0xFFFFFFFF)
+ return bits;
-+
++
+ maskaddr = 0xFFFFFFFE;
+ while (--bits >= 0 && maskaddr != mask)
+ maskaddr <<= 1;
-+
++
+ return bits;
+}
+
+range_to_mask(ip_set_ip_t from, ip_set_ip_t to, unsigned int *bits)
+{
+ ip_set_ip_t mask = 0xFFFFFFFE;
-+
++
+ *bits = 32;
+ while (--(*bits) >= 0 && mask && (to & mask) != from)
+ mask <<= 1;
-+
++
+ return mask;
+}
-+
++
+#endif /* __IP_SET_IPMAP_H */
--- /dev/null
+++ b/include/linux/netfilter_ipv4/ip_set_ipporthash.h
+ void *arrays[0];
+};
+
-+static inline void *
++static inline void *
+harray_malloc(size_t hashsize, size_t typesize, int flags)
+{
+ struct harray *harray;
+ size = hashsize/max_elements;
+ if (hashsize % max_elements)
+ size++;
-+
++
+ /* Last pointer signals end of arrays */
+ harray = kmalloc(sizeof(struct harray) + (size + 1) * sizeof(void *),
+ flags);
+
+ if (!harray)
+ return NULL;
-+
++
+ for (i = 0; i < size - 1; i++) {
+ harray->arrays[i] = kmalloc(max_elements * typesize, flags);
+ if (!harray->arrays[i])
+ goto undo;
+ memset(harray->arrays[i], 0, max_elements * typesize);
+ }
-+ harray->arrays[i] = kmalloc((hashsize - i * max_elements) * typesize,
++ harray->arrays[i] = kmalloc((hashsize - i * max_elements) * typesize,
+ flags);
+ if (!harray->arrays[i])
+ goto undo;
+
+ harray->max_elements = max_elements;
+ harray->arrays[size] = NULL;
-+
++
+ return (void *)harray;
+
+ undo:
+{
+ struct harray *harray = (struct harray *) h;
+ size_t i;
-+
++
+ for (i = 0; harray->arrays[i] != NULL; i++)
+ kfree(harray->arrays[i]);
+ kfree(harray);
+{
+ struct harray *harray = (struct harray *) h;
+ size_t i;
-+
++
+ for (i = 0; harray->arrays[i+1] != NULL; i++)
+ memset(harray->arrays[i], 0, harray->max_elements * typesize);
-+ memset(harray->arrays[i], 0,
++ memset(harray->arrays[i], 0,
+ (hashsize - i * harray->max_elements) * typesize);
+}
+
+
+static unsigned char shifts[] = {255, 253, 249, 241, 225, 193, 129, 1};
+
-+static inline ip_set_ip_t
++static inline ip_set_ip_t
+pack(ip_set_ip_t ip, unsigned char cidr)
+{
+ ip_set_ip_t addr, *paddr = &addr;
+ DP("ip:%u.%u.%u.%u/%u", NIPQUAD(addr), cidr);
+#endif
+ n = cidr / 8;
-+ t = cidr % 8;
++ t = cidr % 8;
+ a = &((unsigned char *)paddr)[n];
+ *a = *a /(1 << (8 - t)) + shifts[t];
+#ifdef __KERNEL__
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
++ * published by the Free Software Foundation.
+ */
+
+/* Kernel module for IP set management */
+
+/*
+ * Sets are identified either by the index in ip_set_list or by id.
-+ * The id never changes and is used to find a key in the hash.
-+ * The index may change by swapping and used at all other places
++ * The id never changes and is used to find a key in the hash.
++ * The index may change by swapping and used at all other places
+ * (set/SET netfilter modules, binding value, etc.)
+ *
+ * Userspace requests are serialized by ip_set_mutex and sets can
-+ * be deleted only from userspace. Therefore ip_set_list locking
++ * be deleted only from userspace. Therefore ip_set_list locking
+ * must obey the following rules:
+ *
+ * - kernel requests: read and write locking mandatory
+ list_for_each_entry(set_hash, &ip_set_hash[key], list)
+ if (set_hash->id == id && set_hash->ip == ip)
+ return set_hash;
-+
++
+ return NULL;
+}
+
+static ip_set_id_t
+ip_set_find_in_hash(ip_set_id_t id, ip_set_ip_t ip)
+{
-+ u_int32_t key = jhash_2words(id, ip, ip_set_hash_random)
++ u_int32_t key = jhash_2words(id, ip, ip_set_hash_random)
+ % ip_set_bindings_hash_size;
+ struct ip_set_hash *set_hash;
+
+ ASSERT_READ_LOCK(&ip_set_lock);
+ IP_SET_ASSERT(ip_set_list[id]);
-+ DP("set: %s, ip: %u.%u.%u.%u", ip_set_list[id]->name, HIPQUAD(ip));
-+
++ DP("set: %s, ip: %u.%u.%u.%u", ip_set_list[id]->name, HIPQUAD(ip));
++
+ set_hash = __ip_set_find(key, id, ip);
-+
-+ DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name,
++
++ DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name,
+ HIPQUAD(ip),
+ set_hash != NULL ? ip_set_list[set_hash->binding]->name : "");
+
+ return (set_hash != NULL ? set_hash->binding : IP_SET_INVALID_ID);
+}
+
-+static inline void
++static inline void
+__set_hash_del(struct ip_set_hash *set_hash)
+{
+ ASSERT_WRITE_LOCK(&ip_set_lock);
-+ IP_SET_ASSERT(ip_set_list[set_hash->binding]);
++ IP_SET_ASSERT(ip_set_list[set_hash->binding]);
+
+ __ip_set_put(set_hash->binding);
+ list_del(&set_hash->list);
+ u_int32_t key = jhash_2words(id, ip, ip_set_hash_random)
+ % ip_set_bindings_hash_size;
+ struct ip_set_hash *set_hash;
-+
++
+ IP_SET_ASSERT(ip_set_list[id]);
-+ DP("set: %s, ip: %u.%u.%u.%u", ip_set_list[id]->name, HIPQUAD(ip));
++ DP("set: %s, ip: %u.%u.%u.%u", ip_set_list[id]->name, HIPQUAD(ip));
+ write_lock_bh(&ip_set_lock);
+ set_hash = __ip_set_find(key, id, ip);
+ DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name,
+ return 0;
+}
+
-+static int
++static int
+ip_set_hash_add(ip_set_id_t id, ip_set_ip_t ip, ip_set_id_t binding)
+{
+ u_int32_t key = jhash_2words(id, ip, ip_set_hash_random)
+ % ip_set_bindings_hash_size;
+ struct ip_set_hash *set_hash;
+ int ret = 0;
-+
++
+ IP_SET_ASSERT(ip_set_list[id]);
+ IP_SET_ASSERT(ip_set_list[binding]);
-+ DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name,
++ DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name,
+ HIPQUAD(ip), ip_set_list[binding]->name);
+ write_lock_bh(&ip_set_lock);
+ set_hash = __ip_set_find(key, id, ip);
+ set_hash->ip = ip;
+ list_add(&set_hash->list, &ip_set_hash[key]);
+ } else {
-+ IP_SET_ASSERT(ip_set_list[set_hash->binding]);
++ IP_SET_ASSERT(ip_set_list[set_hash->binding]);
+ DP("overwrite binding: %s",
+ ip_set_list[set_hash->binding]->name);
+ __ip_set_put(set_hash->binding);
+ ip_set_ip_t ip;
+ int res;
+ unsigned char i = 0;
-+
++
+ IP_SET_ASSERT(flags[i]);
+ read_lock_bh(&ip_set_lock);
+ do {
+ res = set->type->testip_kernel(set, skb, &ip, flags, i++);
+ read_unlock_bh(&set->lock);
+ i += !!(set->type->features & IPSET_DATA_DOUBLE);
-+ } while (res > 0
-+ && flags[i]
++ } while (res > 0
++ && flags[i]
+ && follow_bindings(index, set, ip));
+ read_unlock_bh(&ip_set_lock);
+
+ write_unlock_bh(&set->lock);
+ i += !!(set->type->features & IPSET_DATA_DOUBLE);
+ } while ((res == 0 || res == -EEXIST)
-+ && flags[i]
++ && flags[i]
+ && follow_bindings(index, set, ip));
+ read_unlock_bh(&ip_set_lock);
+
+ write_unlock_bh(&set->lock);
+ i += !!(set->type->features & IPSET_DATA_DOUBLE);
+ } while ((res == 0 || res == -EEXIST)
-+ && flags[i]
++ && flags[i]
+ && follow_bindings(index, set, ip));
+ read_unlock_bh(&ip_set_lock);
+}
+ return NULL;
+}
+
-+int
++int
+ip_set_register_set_type(struct ip_set_type *set_type)
+{
+ int ret = 0;
-+
++
+ if (set_type->protocol_version != IP_SET_PROTOCOL_VERSION) {
+ ip_set_printk("'%s' uses wrong protocol version %u (want %u)",
+ set_type->typename,
+ write_lock_bh(&ip_set_lock);
+ if (find_set_type(set_type->typename)) {
+ /* Duplicate! */
-+ ip_set_printk("'%s' already registered!",
++ ip_set_printk("'%s' already registered!",
+ set_type->typename);
+ ret = -EINVAL;
+ goto unlock;
+ip_set_get_byname(const char *name)
+{
+ ip_set_id_t i, index = IP_SET_INVALID_ID;
-+
++
+ down(&ip_set_app_mutex);
+ for (i = 0; i < ip_set_max; i++) {
+ if (ip_set_list[i] != NULL
+
+ if (index >= ip_set_max)
+ return IP_SET_INVALID_ID;
-+
++
+ if (ip_set_list[index])
+ __ip_set_get(index);
+ else
+ index = IP_SET_INVALID_ID;
-+
++
+ up(&ip_set_app_mutex);
+ return index;
+}
+ip_set_find_byname(const char *name)
+{
+ ip_set_id_t i, index = IP_SET_INVALID_ID;
-+
++
+ for (i = 0; i < ip_set_max; i++) {
+ if (ip_set_list[i] != NULL
+ && strcmp(ip_set_list[i]->name, name) == 0) {
+{
+ if (index >= ip_set_max || ip_set_list[index] == NULL)
+ index = IP_SET_INVALID_ID;
-+
++
+ return index;
+}
+
+ struct ip_set *set = ip_set_list[index];
+ ip_set_ip_t ip;
+ int res;
-+
++
+ IP_SET_ASSERT(set);
+ do {
+ write_lock_bh(&set->lock);
+ struct ip_set *set = ip_set_list[index];
+ ip_set_ip_t ip;
+ int res;
-+
++
+ IP_SET_ASSERT(set);
+ write_lock_bh(&set->lock);
+ res = set->type->delip(set,
+ IP_SET_ASSERT(set);
+ if (size < sizeof(struct ip_set_req_bind))
+ return -EINVAL;
-+
++
+ req_bind = (struct ip_set_req_bind *) data;
+ req_bind->binding[IP_SET_MAXNAMELEN - 1] = '\0';
+
+ if (strcmp(req_bind->binding, IPSET_TOKEN_DEFAULT) == 0) {
+ /* Default binding of a set */
+ char *binding_name;
-+
++
+ if (size != sizeof(struct ip_set_req_bind) + IP_SET_MAXNAMELEN)
+ return -EINVAL;
+
-+ binding_name = (char *)(data + sizeof(struct ip_set_req_bind));
++ binding_name = (char *)(data + sizeof(struct ip_set_req_bind));
+ binding_name[IP_SET_MAXNAMELEN - 1] = '\0';
+
+ binding = ip_set_find_byname(binding_name);
+ &ip);
+ DP("set %s, ip: %u.%u.%u.%u, binding %s",
+ set->name, HIPQUAD(ip), ip_set_list[binding]->name);
-+
++
+ if (res >= 0)
+ res = ip_set_hash_add(set->id, ip, binding);
+
+ DP("");
+ if (size < sizeof(struct ip_set_req_bind))
+ return -EINVAL;
-+
++
+ req_bind = (struct ip_set_req_bind *) data;
+ req_bind->binding[IP_SET_MAXNAMELEN - 1] = '\0';
-+
++
+ DP("%u %s", index, req_bind->binding);
+ if (index == IP_SET_INVALID_ID) {
+ /* unbind :all: */
+ DP("unreachable reached!");
+ return -EINVAL;
+ }
-+
++
+ set = ip_set_list[index];
+ IP_SET_ASSERT(set);
+ if (strcmp(req_bind->binding, IPSET_TOKEN_DEFAULT) == 0) {
+
+ if (binding == IP_SET_INVALID_ID)
+ return -ENOENT;
-+
++
+ write_lock_bh(&ip_set_lock);
+ /* Sets in hash values are referenced */
+ __ip_set_put(set->binding);
+ write_unlock_bh(&ip_set_lock);
+ return 0;
+ }
-+
++
+ res = __ip_set_testip(set,
+ data + sizeof(struct ip_set_req_bind),
+ size - sizeof(struct ip_set_req_bind),
+ IP_SET_ASSERT(set);
+ if (size < sizeof(struct ip_set_req_bind))
+ return -EINVAL;
-+
++
+ req_bind = (struct ip_set_req_bind *) data;
+ req_bind->binding[IP_SET_MAXNAMELEN - 1] = '\0';
+
+ if (strcmp(req_bind->binding, IPSET_TOKEN_DEFAULT) == 0) {
+ /* Default binding of set */
+ char *binding_name;
-+
++
+ if (size != sizeof(struct ip_set_req_bind) + IP_SET_MAXNAMELEN)
+ return -EINVAL;
+
-+ binding_name = (char *)(data + sizeof(struct ip_set_req_bind));
++ binding_name = (char *)(data + sizeof(struct ip_set_req_bind));
+ binding_name[IP_SET_MAXNAMELEN - 1] = '\0';
+
+ binding = ip_set_find_byname(binding_name);
+ if (binding == IP_SET_INVALID_ID)
+ return -ENOENT;
-+
++
+ res = (set->binding == binding) ? -EEXIST : 0;
+
+ return res;
+ binding = ip_set_find_byname(req_bind->binding);
+ if (binding == IP_SET_INVALID_ID)
+ return -ENOENT;
-+
-+
++
++
+ res = __ip_set_testip(set,
+ data + sizeof(struct ip_set_req_bind),
+ size - sizeof(struct ip_set_req_bind),
+ &ip);
+ DP("set %s, ip: %u.%u.%u.%u, binding %s",
+ set->name, HIPQUAD(ip), ip_set_list[binding]->name);
-+
++
+ if (res >= 0)
+ res = (ip_set_find_in_hash(set->id, ip) == binding)
+ ? -EEXIST : 0;
+find_set_type_rlock(const char *typename)
+{
+ struct ip_set_type *type;
-+
++
+ read_lock_bh(&ip_set_lock);
+ type = find_set_type(typename);
+ if (type == NULL)
+ /* No free slot remained */
+ return -ERANGE;
+ /* Check that index is usable as id (swapping) */
-+ check:
++ check:
+ for (i = 0; i < ip_set_max; i++) {
+ if (ip_set_list[i] != NULL
+ && ip_set_list[i]->id == *id) {
+
+ /*
+ * Here, we have a valid, constructed set. &ip_set_lock again,
-+ * find free id/index and check that it is not already in
++ * find free id/index and check that it is not already in
+ * ip_set_list.
+ */
+ write_lock_bh(&ip_set_lock);
+ res = -ERANGE;
+ goto cleanup;
+ }
-+
++
+ /*
+ * Finally! Add our shiny new set to the list, and be done.
+ */
+ ip_set_list[index] = set;
+ write_unlock_bh(&ip_set_lock);
+ return res;
-+
++
+ cleanup:
+ write_unlock_bh(&ip_set_lock);
+ set->type->destroy(set);
+ ip_set_destroy_set(index);
+ } else {
+ for (i = 0; i < ip_set_max; i++) {
-+ if (ip_set_list[i] != NULL
++ if (ip_set_list[i] != NULL
+ && (atomic_read(&ip_set_list[i]->ref)))
+ return -EBUSY;
+ }
+ write_unlock_bh(&set->lock);
+}
+
-+/*
++/*
+ * Flush data in a set - or in all sets
+ */
+static int
+ write_lock_bh(&ip_set_lock);
+ for (i = 0; i < ip_set_max; i++) {
+ if (ip_set_list[i] != NULL
-+ && strncmp(ip_set_list[i]->name,
++ && strncmp(ip_set_list[i]->name,
+ name,
+ IP_SET_MAXNAMELEN - 1) == 0) {
+ res = -EEXIST;
+ if (from->type->features != to->type->features)
+ return -ENOEXEC;
+
-+ /* No magic here: ref munging protected by the mutex */
++ /* No magic here: ref munging protected by the mutex */
+ write_lock_bh(&ip_set_lock);
+ strncpy(from_name, from->name, IP_SET_MAXNAMELEN);
+ from_ref = atomic_read(&from->ref);
+ atomic_set(&from->ref, atomic_read(&to->ref));
+ strncpy(to->name, from_name, IP_SET_MAXNAMELEN);
+ atomic_set(&to->ref, from_ref);
-+
++
+ ip_set_list[from_index] = to;
+ ip_set_list[to_index] = from;
-+
++
+ write_unlock_bh(&ip_set_lock);
+ return 0;
+}
+ ip_set_id_t id, void *data, int *used)
+{
+ if (set_hash->id == id) {
-+ struct ip_set_hash_list *hash_list =
++ struct ip_set_hash_list *hash_list =
+ (struct ip_set_hash_list *)(data + *used);
+
+ hash_list->ip = set_hash->ip;
+
+ /* Fill in set spefific bindings data */
+ FOREACH_HASH_DO(__set_hash_bindings, set->id, data, used);
-+
++
+ return 0;
+
+ unlock_set:
+ *used += sizeof(struct ip_set_save);
+
+ set = ip_set_list[index];
-+ DP("set: %s, used: %u(%u) %p %p", set->name, *used, len,
++ DP("set: %s, used: %u(%u) %p %p", set->name, *used, len,
+ data, data + *used);
+
+ read_lock_bh(&set->lock);
+{
+ if (*res == 0
+ && (id == IP_SET_INVALID_ID || set_hash->id == id)) {
-+ struct ip_set_hash_save *hash_save =
++ struct ip_set_hash_save *hash_save =
+ (struct ip_set_hash_save *)(data + *used);
+ /* Ensure bindings size */
+ if (*used + sizeof(struct ip_set_hash_save) > len) {
+ index = ip_set_list[index]->id;
+ FOREACH_HASH_DO(__set_hash_save_bindings, index, data, used, len, &res);
+
-+ return res;
++ return res;
+}
+
+/*
+ /* Loop to restore sets */
+ while (1) {
+ line++;
-+
++
+ DP("%u %u %u", used, sizeof(struct ip_set_restore), len);
+ /* Get and ensure header size */
+ if (used + sizeof(struct ip_set_restore) > len)
+ used += sizeof(struct ip_set_restore);
+
+ /* Ensure data size */
-+ if (used
-+ + set_restore->header_size
++ if (used
++ + set_restore->header_size
+ + set_restore->members_size > len)
+ return line;
+
+ line--;
+ goto bindings;
+ }
-+
++
+ /* Try to create the set */
+ DP("restore %s %s", set_restore->name, set_restore->typename);
+ res = ip_set_create(set_restore->name,
+ set_restore->index,
+ data + used,
+ set_restore->header_size);
-+
++
+ if (res != 0)
+ return line;
+ used += set_restore->header_size;
+ res = __ip_set_addip(index,
+ data + used + members_size,
+ set->type->reqsize);
-+ if (!(res == 0 || res == -EEXIST))
++ if (!(res == 0 || res == -EEXIST))
+ return line;
+ members_size += set->type->reqsize;
+ }
+ set_restore->members_size, members_size);
+ if (members_size != set_restore->members_size)
+ return line++;
-+ used += set_restore->members_size;
++ used += set_restore->members_size;
+ }
-+
++
+ bindings:
+ /* Loop to restore bindings */
+ while (used < len) {
+ line++;
+
-+ DP("restore binding, line %u", line);
++ DP("restore binding, line %u", line);
+ /* Get and ensure size */
+ if (used + sizeof(struct ip_set_hash_save) > len)
+ return line;
+ hash_save = (struct ip_set_hash_save *) (data + used);
+ used += sizeof(struct ip_set_hash_save);
-+
++
+ /* hash_save->id is used to store the index */
+ index = ip_set_find_byindex(hash_save->id);
+ DP("restore binding index %u, id %u, %u -> %u",
-+ index, hash_save->id, hash_save->ip, hash_save->binding);
++ index, hash_save->id, hash_save->ip, hash_save->binding);
+ if (index != hash_save->id)
+ return line;
+ if (ip_set_find_byindex(hash_save->binding) == IP_SET_INVALID_ID) {
+ set = ip_set_list[hash_save->id];
+ /* Null valued IP means default binding */
+ if (hash_save->ip)
-+ res = ip_set_hash_add(set->id,
++ res = ip_set_hash_add(set->id,
+ hash_save->ip,
+ hash_save->binding);
+ else {
+ }
+ if (used != len)
+ return line;
-+
-+ return 0;
++
++ return 0;
+}
+
+static int
+
+ op = (unsigned *)data;
+ DP("op=%x", *op);
-+
++
+ if (*op < IP_SET_OP_VERSION) {
+ /* Check the version at the beginning of operations */
+ struct ip_set_req_version *req_version =
+ case IP_SET_OP_CREATE:{
+ struct ip_set_req_create *req_create
+ = (struct ip_set_req_create *) data;
-+
++
+ if (len < sizeof(struct ip_set_req_create)) {
+ ip_set_printk("short CREATE data (want >=%zu, got %u)",
+ sizeof(struct ip_set_req_create), len);
+ case IP_SET_OP_DESTROY:{
+ struct ip_set_req_std *req_destroy
+ = (struct ip_set_req_std *) data;
-+
++
+ if (len != sizeof(struct ip_set_req_std)) {
+ ip_set_printk("invalid DESTROY data (want %zu, got %u)",
+ sizeof(struct ip_set_req_std), len);
+ goto done;
+ }
+ }
-+
++
+ res = ip_set_destroy(index);
+ goto done;
+ }
+
+ req_rename->name[IP_SET_MAXNAMELEN - 1] = '\0';
+ req_rename->typename[IP_SET_MAXNAMELEN - 1] = '\0';
-+
++
+ index = ip_set_find_byname(req_rename->name);
+ if (index == IP_SET_INVALID_ID) {
+ res = -ENOENT;
+ res = ip_set_swap(index, to_index);
+ goto done;
+ }
-+ default:
++ default:
+ break; /* Set identified by id */
+ }
-+
++
+ /* There we may have add/del/test/bind/unbind/test_bind operations */
+ if (*op < IP_SET_OP_ADD_IP || *op > IP_SET_OP_TEST_BIND_SET) {
+ res = -EBADMSG;
+ req_adt = (struct ip_set_req_adt *) data;
+
+ /* -U :all: :all:|:default: uses IP_SET_INVALID_ID */
-+ if (!(*op == IP_SET_OP_UNBIND_SET
++ if (!(*op == IP_SET_OP_UNBIND_SET
+ && req_adt->index == IP_SET_INVALID_ID)) {
+ index = ip_set_find_byindex(req_adt->index);
+ if (index == IP_SET_INVALID_ID) {
+ return res;
+}
+
-+static int
++static int
+ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
+{
+ int res = 0;
+ req_max_sets->set.index = IP_SET_INVALID_ID;
+ } else {
+ req_max_sets->set.name[IP_SET_MAXNAMELEN - 1] = '\0';
-+ req_max_sets->set.index =
++ req_max_sets->set.index =
+ ip_set_find_byname(req_max_sets->set.name);
+ if (req_max_sets->set.index == IP_SET_INVALID_ID) {
+ res = -ENOENT;
+ }
+ goto copy;
+ }
-+ case IP_SET_OP_LIST_SIZE:
++ case IP_SET_OP_LIST_SIZE:
+ case IP_SET_OP_SAVE_SIZE: {
+ struct ip_set_req_setnames *req_setnames
+ = (struct ip_set_req_setnames *) data;
+ for (i = 0; i < ip_set_max; i++) {
+ if (ip_set_list[i] == NULL)
+ continue;
-+ name_list = (struct ip_set_name_list *)
++ name_list = (struct ip_set_name_list *)
+ (data + used);
+ used += sizeof(struct ip_set_name_list);
+ if (used > copylen) {
+ + set->type->header_size
+ + set->type->list_members_size(set);
+ /* Sets are identified by id in the hash */
-+ FOREACH_HASH_DO(__set_hash_bindings_size_list,
++ FOREACH_HASH_DO(__set_hash_bindings_size_list,
+ set->id, &req_setnames->size);
+ break;
+ }
+ }
+ if (res == 0)
+ res = ip_set_save_bindings(index, data, &used, *len);
-+
++
+ if (res != 0)
+ goto done;
+ else if (copylen != used) {
+ ? ip_set_list[index]->name
+ : ":all:", copylen);
+ res = copy_to_user(user, data, copylen);
-+
++
+ done:
+ up(&ip_set_app_mutex);
+ vfree(data);
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
++ * published by the Free Software Foundation.
+ */
+
+/* Kernel module implementing an ip hash set */
+ *hash_ip = ip & map->netmask;
+ DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u, %u.%u.%u.%u",
+ set->name, HIPQUAD(ip), HIPQUAD(*hash_ip), HIPQUAD(map->netmask));
-+
++
+ for (i = 0; i < map->probes; i++) {
+ id = jhash_ip(map, i, *hash_ip) % map->hashsize;
+ DP("hash key: %u", id);
+testip(struct ip_set *set, const void *data, size_t size,
+ ip_set_ip_t *hash_ip)
+{
-+ struct ip_set_req_iphash *req =
++ struct ip_set_req_iphash *req =
+ (struct ip_set_req_iphash *) data;
+
+ if (size != sizeof(struct ip_set_req_iphash)) {
+}
+
+static int
-+testip_kernel(struct ip_set *set,
++testip_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+ unsigned char index)
+{
+ return __testip(set,
-+ ntohl(flags[index] & IPSET_SRC
++ ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr),
+#else
-+ ? skb->nh.iph->saddr
++ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+#endif
+ hash_ip);
+ __u32 probe;
+ u_int16_t i;
+ ip_set_ip_t *elem;
-+
++
+ if (!ip || map->elements >= limit)
+ return -ERANGE;
+
+ *hash_ip = ip & map->netmask;
-+
++
+ for (i = 0; i < map->probes; i++) {
+ probe = jhash_ip(map, i, *hash_ip) % map->hashsize;
+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, probe);
+addip(struct ip_set *set, const void *data, size_t size,
+ ip_set_ip_t *hash_ip)
+{
-+ struct ip_set_req_iphash *req =
++ struct ip_set_req_iphash *req =
+ (struct ip_set_req_iphash *) data;
+
+ if (size != sizeof(struct ip_set_req_iphash)) {
+}
+
+static int
-+addip_kernel(struct ip_set *set,
++addip_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+ unsigned char index)
+{
+ return __addip((struct ip_set_iphash *) set->data,
-+ ntohl(flags[index] & IPSET_SRC
++ ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr),
+#else
-+ ? skb->nh.iph->saddr
++ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+#endif
+ hash_ip);
+ u_int32_t i, hashsize = map->hashsize;
+ int res;
+ struct ip_set_iphash *tmp;
-+
++
+ if (map->resize == 0)
+ return -ERANGE;
+
+ again:
+ res = 0;
-+
++
+ /* Calculate new hash size */
+ hashsize += (hashsize * map->resize)/100;
+ if (hashsize == map->hashsize)
+ hashsize++;
-+
++
+ ip_set_printk("rehashing of set %s triggered: "
+ "hashsize grows from %u to %u",
+ set->name, map->hashsize, hashsize);
+
-+ tmp = kmalloc(sizeof(struct ip_set_iphash)
++ tmp = kmalloc(sizeof(struct ip_set_iphash)
+ + map->probes * sizeof(uint32_t), GFP_ATOMIC);
+ if (!tmp) {
+ DP("out of memory for %d bytes",
+ tmp->resize = map->resize;
+ tmp->netmask = map->netmask;
+ memcpy(tmp->initval, map->initval, map->probes * sizeof(uint32_t));
-+
++
+ write_lock_bh(&set->lock);
+ map = (struct ip_set_iphash *) set->data; /* Play safe */
+ for (i = 0; i < map->hashsize && res == 0; i++) {
-+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
++ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
+ if (*elem)
+ res = __addip(tmp, *elem, &hash_ip);
+ }
+ kfree(tmp);
+ goto again;
+ }
-+
++
+ /* Success at resizing! */
+ members = map->members;
+
+ id = hash_id(set, ip, hash_ip);
+ if (id == UINT_MAX)
+ return -EEXIST;
-+
++
+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
+ *elem = 0;
+ map->elements--;
+}
+
+static int
-+delip_kernel(struct ip_set *set,
++delip_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+ unsigned char index)
+{
+ return __delip(set,
-+ ntohl(flags[index] & IPSET_SRC
++ ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr),
+#else
-+ ? skb->nh.iph->saddr
++ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+#endif
+ hash_ip);
+ return -ENOEXEC;
+ }
+
-+ map = kmalloc(sizeof(struct ip_set_iphash)
++ map = kmalloc(sizeof(struct ip_set_iphash)
+ + req->probes * sizeof(uint32_t), GFP_KERNEL);
+ if (!map) {
+ DP("out of memory for %d bytes",
+ ip_set_ip_t i, *elem;
+
+ for (i = 0; i < map->hashsize; i++) {
-+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
++ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
+ ((ip_set_ip_t *)data)[i] = *elem;
+ }
+}
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
++ * published by the Free Software Foundation.
+ */
+
+/* Kernel module implementing an IP set type: the single bitmap type */
+__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
+{
+ struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data;
-+
++
+ if (ip < map->first_ip || ip > map->last_ip)
+ return -ERANGE;
+
+testip(struct ip_set *set, const void *data, size_t size,
+ ip_set_ip_t *hash_ip)
+{
-+ struct ip_set_req_ipmap *req =
++ struct ip_set_req_ipmap *req =
+ (struct ip_set_req_ipmap *) data;
+
+ if (size != sizeof(struct ip_set_req_ipmap)) {
+}
+
+static int
-+testip_kernel(struct ip_set *set,
++testip_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+ int res = __testip(set,
+ ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr),
+#else
-+ ? skb->nh.iph->saddr
++ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+#endif
+ hash_ip);
+addip(struct ip_set *set, const void *data, size_t size,
+ ip_set_ip_t *hash_ip)
+{
-+ struct ip_set_req_ipmap *req =
++ struct ip_set_req_ipmap *req =
+ (struct ip_set_req_ipmap *) data;
+
+ if (size != sizeof(struct ip_set_req_ipmap)) {
+}
+
+static int
-+addip_kernel(struct ip_set *set,
++addip_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+ unsigned char index)
+{
+ return __addip(set,
-+ ntohl(flags[index] & IPSET_SRC
++ ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr),
+#else
-+ ? skb->nh.iph->saddr
++ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+#endif
+ hash_ip);
+}
+
-+static inline int
++static inline int
+__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
+{
+ struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data;
+ DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
+ if (!test_and_clear_bit(ip_to_id(map, *hash_ip), map->members))
+ return -EEXIST;
-+
++
+ return 0;
+}
+
+ unsigned char index)
+{
+ return __delip(set,
-+ ntohl(flags[index] & IPSET_SRC
++ ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr),
+#else
-+ ? skb->nh.iph->saddr
++ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+#endif
+ hash_ip);
+ } else {
+ unsigned int mask_bits, netmask_bits;
+ ip_set_ip_t mask;
-+
++
+ map->first_ip &= map->netmask; /* Should we better bark? */
-+
++
+ mask = range_to_mask(map->first_ip, map->last_ip, &mask_bits);
+ netmask_bits = mask_to_bits(map->netmask);
-+
++
+ if ((!mask && (map->first_ip || map->last_ip != 0xFFFFFFFF))
+ || netmask_bits <= mask_bits)
+ return -ENOEXEC;
+ return -ENOMEM;
+ }
+ memset(map->members, 0, newbytes);
-+
++
+ set->data = map;
+ return 0;
+}
+static void destroy(struct ip_set *set)
+{
+ struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data;
-+
++
+ kfree(map->members);
+ kfree(map);
-+
++
+ set->data = NULL;
+}
+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
++ * published by the Free Software Foundation.
+ */
+
+/* Kernel module implementing an ip+port hash set */
+ switch (iph->protocol) {
+ case IPPROTO_TCP: {
+ struct tcphdr tcph;
-+
++
+ /* See comments at tcp_match in ip_tables.c */
+ if (offset)
+ return INVALID_PORT;
+#endif
+ /* No choice either */
+ return INVALID_PORT;
-+
++
+ return ntohs(flags & IPSET_SRC ?
+ tcph.source : tcph.dest);
+ }
+#endif
+ /* No choice either */
+ return INVALID_PORT;
-+
++
+ return ntohs(flags & IPSET_SRC ?
+ udph.source : udph.dest);
+ }
+hash_id(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port,
+ ip_set_ip_t *hash_ip)
+{
-+ struct ip_set_ipporthash *map =
++ struct ip_set_ipporthash *map =
+ (struct ip_set_ipporthash *) set->data;
+ __u32 id;
+ u_int16_t i;
+ *hash_ip = HASH_IP(map, ip, port);
+ DP("set: %s, ipport:%u.%u.%u.%u:%u, %u.%u.%u.%u",
+ set->name, HIPQUAD(ip), port, HIPQUAD(*hash_ip));
-+
++
+ for (i = 0; i < map->probes; i++) {
+ id = jhash_ip(map, i, *hash_ip) % map->hashsize;
+ DP("hash key: %u", id);
+ ip_set_ip_t *hash_ip)
+{
+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
-+
++
+ if (ip < map->first_ip || ip > map->last_ip)
+ return -ERANGE;
+
+testip(struct ip_set *set, const void *data, size_t size,
+ ip_set_ip_t *hash_ip)
+{
-+ struct ip_set_req_ipporthash *req =
++ struct ip_set_req_ipporthash *req =
+ (struct ip_set_req_ipporthash *) data;
+
+ if (size != sizeof(struct ip_set_req_ipporthash)) {
+}
+
+static int
-+testip_kernel(struct ip_set *set,
++testip_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+
+ if (flags[index+1] == 0)
+ return 0;
-+
++
+ port = get_port(skb, flags[index+1]);
+
+ DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u",
+ NIPQUAD(skb->nh.iph->daddr));
+#endif
+ DP("flag %s port %u",
-+ flags[index+1] & IPSET_SRC ? "SRC" : "DST",
-+ port);
++ flags[index+1] & IPSET_SRC ? "SRC" : "DST",
++ port);
+ if (port == INVALID_PORT)
-+ return 0;
++ return 0;
+
+ res = __testip(set,
-+ ntohl(flags[index] & IPSET_SRC
++ ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr),
+#else
-+ ? skb->nh.iph->saddr
++ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+#endif
+ port,
+ hash_ip);
+ return (res < 0 ? 0 : res);
-+
++
+}
+
+static inline int
+ return -ERANGE;
+
+ *hash_ip = HASH_IP(map, ip, port);
-+
++
+ return __add_haship(map, *hash_ip);
+}
+
+addip(struct ip_set *set, const void *data, size_t size,
+ ip_set_ip_t *hash_ip)
+{
-+ struct ip_set_req_ipporthash *req =
++ struct ip_set_req_ipporthash *req =
+ (struct ip_set_req_ipporthash *) data;
+
+ if (size != sizeof(struct ip_set_req_ipporthash)) {
+ size);
+ return -EINVAL;
+ }
-+ return __addip((struct ip_set_ipporthash *) set->data,
++ return __addip((struct ip_set_ipporthash *) set->data,
+ req->ip, req->port, hash_ip);
+}
+
+static int
-+addip_kernel(struct ip_set *set,
++addip_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+
+ if (flags[index+1] == 0)
+ return -EINVAL;
-+
++
+ port = get_port(skb, flags[index+1]);
+
+ DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u",
+ NIPQUAD(skb->nh.iph->saddr),
+ NIPQUAD(skb->nh.iph->daddr));
+#endif
-+ DP("flag %s port %u",
-+ flags[index+1] & IPSET_SRC ? "SRC" : "DST",
-+ port);
++ DP("flag %s port %u",
++ flags[index+1] & IPSET_SRC ? "SRC" : "DST",
++ port);
+ if (port == INVALID_PORT)
-+ return -EINVAL;
++ return -EINVAL;
+
+ return __addip((struct ip_set_ipporthash *) set->data,
-+ ntohl(flags[index] & IPSET_SRC
++ ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr),
+#else
-+ ? skb->nh.iph->saddr
++ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+#endif
+ port,
+ u_int32_t i, hashsize = map->hashsize;
+ int res;
+ struct ip_set_ipporthash *tmp;
-+
++
+ if (map->resize == 0)
+ return -ERANGE;
+
+ again:
+ res = 0;
-+
++
+ /* Calculate new hash size */
+ hashsize += (hashsize * map->resize)/100;
+ if (hashsize == map->hashsize)
+ hashsize++;
-+
++
+ ip_set_printk("rehashing of set %s triggered: "
+ "hashsize grows from %u to %u",
+ set->name, map->hashsize, hashsize);
+
-+ tmp = kmalloc(sizeof(struct ip_set_ipporthash)
++ tmp = kmalloc(sizeof(struct ip_set_ipporthash)
+ + map->probes * sizeof(uint32_t), GFP_ATOMIC);
+ if (!tmp) {
+ DP("out of memory for %d bytes",
+ tmp->first_ip = map->first_ip;
+ tmp->last_ip = map->last_ip;
+ memcpy(tmp->initval, map->initval, map->probes * sizeof(uint32_t));
-+
++
+ write_lock_bh(&set->lock);
+ map = (struct ip_set_ipporthash *) set->data; /* Play safe */
+ for (i = 0; i < map->hashsize && res == 0; i++) {
-+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
++ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
+ if (*elem)
+ res = __add_haship(tmp, *elem);
+ }
+ kfree(tmp);
+ goto again;
+ }
-+
++
+ /* Success at resizing! */
+ members = map->members;
+
+
+ if (id == UINT_MAX)
+ return -EEXIST;
-+
++
+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
+ *elem = 0;
+ map->elements--;
+}
+
+static int
-+delip_kernel(struct ip_set *set,
++delip_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+
+ if (flags[index+1] == 0)
+ return -EINVAL;
-+
++
+ port = get_port(skb, flags[index+1]);
+
+ DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u",
+ NIPQUAD(skb->nh.iph->daddr));
+#endif
+ DP("flag %s port %u",
-+ flags[index+1] & IPSET_SRC ? "SRC" : "DST",
-+ port);
++ flags[index+1] & IPSET_SRC ? "SRC" : "DST",
++ port);
+ if (port == INVALID_PORT)
-+ return -EINVAL;
++ return -EINVAL;
+
+ return __delip(set,
-+ ntohl(flags[index] & IPSET_SRC
++ ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr),
+#else
-+ ? skb->nh.iph->saddr
++ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+#endif
+ port,
+ return -ENOEXEC;
+ }
+
-+ map = kmalloc(sizeof(struct ip_set_ipporthash)
++ map = kmalloc(sizeof(struct ip_set_ipporthash)
+ + req->probes * sizeof(uint32_t), GFP_KERNEL);
+ if (!map) {
+ DP("out of memory for %d bytes",
+ ip_set_ip_t i, *elem;
+
+ for (i = 0; i < map->hashsize; i++) {
-+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
++ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
+ ((ip_set_ip_t *)data)[i] = *elem;
+ }
+}
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
++ * published by the Free Software Foundation.
+ */
+
+/* Kernel module implementing an IP set type: the iptree type */
+
+/* Garbage collection interval in seconds: */
+#define IPTREE_GC_TIME 5*60
-+/* Sleep so many milliseconds before trying again
-+ * to delete the gc timer at destroying/flushing a set */
++/* Sleep so many milliseconds before trying again
++ * to delete the gc timer at destroying/flushing a set */
+#define IPTREE_DESTROY_SLEEP 100
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
+
+ if (!ip)
+ return -ERANGE;
-+
++
+ *hash_ip = ip;
+ ABCD(a, b, c, d, hash_ip);
+ DP("%u %u %u %u timeout %u", a, b, c, d, map->timeout);
+testip(struct ip_set *set, const void *data, size_t size,
+ ip_set_ip_t *hash_ip)
+{
-+ struct ip_set_req_iptree *req =
++ struct ip_set_req_iptree *req =
+ (struct ip_set_req_iptree *) data;
+
+ if (size != sizeof(struct ip_set_req_iptree)) {
+}
+
+static int
-+testip_kernel(struct ip_set *set,
++testip_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+ unsigned char index)
+{
+ int res;
-+
++
+ DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u",
+ flags[index] & IPSET_SRC ? "SRC" : "DST",
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+#endif
+
+ res = __testip(set,
-+ ntohl(flags[index] & IPSET_SRC
++ ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr),
+#else
-+ ? skb->nh.iph->saddr
++ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+#endif
+ hash_ip);
+ (map)->tree[elem] = branch; \
+ DP("alloc %u", elem); \
+ } \
-+} while (0)
++} while (0)
+
+static inline int
+__addip(struct ip_set *set, ip_set_ip_t ip, unsigned int timeout,
+ struct ip_set_iptreed *dtree;
+ unsigned char a,b,c,d;
+ int ret = 0;
-+
++
+ if (!ip || map->elements >= limit)
+ /* We could call the garbage collector
+ * but it's probably overkill */
+ return -ERANGE;
-+
++
+ *hash_ip = ip;
+ ABCD(a, b, c, d, hash_ip);
+ DP("%u %u %u %u timeout %u", a, b, c, d, timeout);
+ ip_set_ip_t *hash_ip)
+{
+ struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
-+ struct ip_set_req_iptree *req =
++ struct ip_set_req_iptree *req =
+ (struct ip_set_req_iptree *) data;
+
+ if (size != sizeof(struct ip_set_req_iptree)) {
+}
+
+static int
-+addip_kernel(struct ip_set *set,
++addip_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+ struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
+
+ return __addip(set,
-+ ntohl(flags[index] & IPSET_SRC
++ ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr),
+#else
-+ ? skb->nh.iph->saddr
++ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+#endif
+ map->timeout,
+ return -EEXIST; \
+} while (0)
+
-+static inline int
++static inline int
+__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
+{
+ struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
+ struct ip_set_iptreec *ctree;
+ struct ip_set_iptreed *dtree;
+ unsigned char a,b,c,d;
-+
++
+ if (!ip)
+ return -ERANGE;
-+
++
+ *hash_ip = ip;
+ ABCD(a, b, c, d, hash_ip);
+ DELIP_WALK(map, a, btree);
+}
+
+static int
-+delip_kernel(struct ip_set *set,
++delip_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+ unsigned char index)
+{
+ return __delip(set,
-+ ntohl(flags[index] & IPSET_SRC
++ ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr),
+#else
-+ ? skb->nh.iph->saddr
++ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+#endif
+ hash_ip);
+ }
+ LOOP_WALK_END;
+ write_unlock_bh(&set->lock);
-+
++
+ map->gc.expires = jiffies + map->gc_interval * HZ;
+ add_timer(&map->gc);
+}
+{
+ struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
+ unsigned int timeout = map->timeout;
-+
++
+ /* gc might be running */
+ while (!del_timer(&map->gc))
+ msleep(IPTREE_DESTROY_SLEEP);
+ && (!map->timeout || time_after(dtree->expires[d], jiffies))) {
+ entry = (struct ip_set_req_iptree *)(data + offset);
+ entry->ip = ((a << 24) | (b << 16) | (c << 8) | d);
-+ entry->timeout = !map->timeout ? 0
++ entry->timeout = !map->timeout ? 0
+ : (dtree->expires[d] - jiffies)/HZ;
+ offset += sizeof(struct ip_set_req_iptree);
+ }
+static int __init ip_set_iptree_init(void)
+{
+ int ret;
-+
++
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
+ branch_cachep = kmem_cache_create("ip_set_iptreeb",
+ sizeof(struct ip_set_iptreeb),
+ goto out;
+
+ kmem_cache_destroy(leaf_cachep);
-+ free_branch:
++ free_branch:
+ kmem_cache_destroy(branch_cachep);
+ out:
+ return ret;
+{
+ int res;
+
-+ res = __testip(set,
-+ ntohl(flags[index] & IPSET_SRC
++ res = __testip(set,
++ ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr),
+#else
-+ ? skb->nh.iph->saddr
++ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+#endif
+ hash_ip);
+{
+
+ return __addip_single(set,
-+ ntohl(flags[index] & IPSET_SRC
++ ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr),
+#else
-+ ? skb->nh.iph->saddr
++ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+#endif
+ hash_ip);
+static int
+delip_kernel(struct ip_set *set, const struct sk_buff *skb, ip_set_ip_t *hash_ip, const u_int32_t *flags, unsigned char index)
+{
-+ return __delip_single(set,
-+ ntohl(flags[index] & IPSET_SRC
++ return __delip_single(set,
++ ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr),
+#else
-+ ? skb->nh.iph->saddr
++ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+#endif
+ hash_ip,
+ int a;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
-+ cachep_b = kmem_cache_create("ip_set_iptreemap_b",
-+ sizeof(struct ip_set_iptreemap_b),
++ cachep_b = kmem_cache_create("ip_set_iptreemap_b",
++ sizeof(struct ip_set_iptreemap_b),
+ 0, 0, NULL);
+#else
-+ cachep_b = kmem_cache_create("ip_set_iptreemap_b",
-+ sizeof(struct ip_set_iptreemap_b),
++ cachep_b = kmem_cache_create("ip_set_iptreemap_b",
++ sizeof(struct ip_set_iptreemap_b),
+ 0, 0, NULL, NULL);
+#endif
+ if (!cachep_b) {
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
-+ cachep_c = kmem_cache_create("ip_set_iptreemap_c",
++ cachep_c = kmem_cache_create("ip_set_iptreemap_c",
+ sizeof(struct ip_set_iptreemap_c),
+ 0, 0, NULL);
+#else
-+ cachep_c = kmem_cache_create("ip_set_iptreemap_c",
++ cachep_c = kmem_cache_create("ip_set_iptreemap_c",
+ sizeof(struct ip_set_iptreemap_c),
+ 0, 0, NULL, NULL);
+#endif
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
++ * published by the Free Software Foundation.
+ */
+
+/* Kernel module implementing an IP set type: the macipmap type */
+testip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip)
+{
+ struct ip_set_macipmap *map = (struct ip_set_macipmap *) set->data;
-+ struct ip_set_macip *table = (struct ip_set_macip *) map->members;
++ struct ip_set_macip *table = (struct ip_set_macip *) map->members;
+ struct ip_set_req_macipmap *req = (struct ip_set_req_macipmap *) data;
+
+ if (size != sizeof(struct ip_set_req_macipmap)) {
+
+ *hash_ip = req->ip;
+ DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
-+ set->name, HIPQUAD(req->ip), HIPQUAD(*hash_ip));
++ set->name, HIPQUAD(req->ip), HIPQUAD(*hash_ip));
+ if (test_bit(IPSET_MACIP_ISSET,
+ (void *) &table[req->ip - map->first_ip].flags)) {
+ return (memcmp(req->ethernet,
+}
+
+static int
-+testip_kernel(struct ip_set *set,
++testip_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+ struct ip_set_macip *table =
+ (struct ip_set_macip *) map->members;
+ ip_set_ip_t ip;
-+
++
+ ip = ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr);
+#else
+ ? skb->nh.iph->saddr
+ if (ip < map->first_ip || ip > map->last_ip)
+ return 0;
+
-+ *hash_ip = ip;
++ *hash_ip = ip;
+ DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
-+ set->name, HIPQUAD(ip), HIPQUAD(*hash_ip));
++ set->name, HIPQUAD(ip), HIPQUAD(*hash_ip));
+ if (test_bit(IPSET_MACIP_ISSET,
+ (void *) &table[ip - map->first_ip].flags)) {
+ /* Is mac pointer valid?
+
+/* returns 0 on success */
+static inline int
-+__addip(struct ip_set *set,
++__addip(struct ip_set *set,
+ ip_set_ip_t ip, unsigned char *ethernet, ip_set_ip_t *hash_ip)
+{
+ struct ip_set_macipmap *map =
+
+ if (ip < map->first_ip || ip > map->last_ip)
+ return -ERANGE;
-+ if (test_and_set_bit(IPSET_MACIP_ISSET,
++ if (test_and_set_bit(IPSET_MACIP_ISSET,
+ (void *) &table[ip - map->first_ip].flags))
+ return -EEXIST;
+
+}
+
+static int
-+addip_kernel(struct ip_set *set,
++addip_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+ unsigned char index)
+{
+ ip_set_ip_t ip;
-+
++
+ ip = ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr);
+#else
+ ? skb->nh.iph->saddr
+
+ if (ip < map->first_ip || ip > map->last_ip)
+ return -ERANGE;
-+ if (!test_and_clear_bit(IPSET_MACIP_ISSET,
++ if (!test_and_clear_bit(IPSET_MACIP_ISSET,
+ (void *)&table[ip - map->first_ip].flags))
+ return -EEXIST;
+
+ unsigned char index)
+{
+ return __delip(set,
-+ ntohl(flags[index] & IPSET_SRC
++ ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr),
+#else
-+ ? skb->nh.iph->saddr
++ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+#endif
+ hash_ip);
+ return -ENOMEM;
+ }
+ memset(map->members, 0, newbytes);
-+
++
+ set->data = map;
+ return 0;
+}
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
++ * published by the Free Software Foundation.
+ */
+
+/* Kernel module implementing a cidr nethash set */
+ ip_set_ip_t *elem;
+
+ *hash_ip = pack(ip, cidr);
-+
++
+ for (i = 0; i < map->probes; i++) {
+ id = jhash_ip(map, i, *hash_ip) % map->hashsize;
+ DP("hash key: %u", id);
+testip(struct ip_set *set, const void *data, size_t size,
+ ip_set_ip_t *hash_ip)
+{
-+ struct ip_set_req_nethash *req =
++ struct ip_set_req_nethash *req =
+ (struct ip_set_req_nethash *) data;
+
+ if (size != sizeof(struct ip_set_req_nethash)) {
+}
+
+static int
-+testip_kernel(struct ip_set *set,
++testip_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+ unsigned char index)
+{
+ return __testip(set,
-+ ntohl(flags[index] & IPSET_SRC
++ ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr),
+#else
-+ ? skb->nh.iph->saddr
++ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+#endif
+ hash_ip);
+ __u32 probe;
+ u_int16_t i;
+ ip_set_ip_t *elem;
-+
++
+ for (i = 0; i < map->probes; i++) {
+ probe = jhash_ip(map, i, ip) % map->hashsize;
+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, probe);
+{
+ if (!ip || map->elements >= limit)
+ return -ERANGE;
-+
++
+ *hash_ip = pack(ip, cidr);
+ DP("%u.%u.%u.%u/%u, %u.%u.%u.%u", HIPQUAD(ip), cidr, HIPQUAD(*hash_ip));
-+
++
+ return __addip_base(map, *hash_ip);
+}
+
+{
+ unsigned char next;
+ int i;
-+
++
+ for (i = 0; i < 30 && map->cidr[i]; i++) {
+ if (map->cidr[i] == cidr) {
+ return;
+addip(struct ip_set *set, const void *data, size_t size,
+ ip_set_ip_t *hash_ip)
+{
-+ struct ip_set_req_nethash *req =
++ struct ip_set_req_nethash *req =
+ (struct ip_set_req_nethash *) data;
+ int ret;
+
+ size);
+ return -EINVAL;
+ }
-+ ret = __addip((struct ip_set_nethash *) set->data,
++ ret = __addip((struct ip_set_nethash *) set->data,
+ req->ip, req->cidr, hash_ip);
-+
++
+ if (ret == 0)
+ update_cidr_sizes((struct ip_set_nethash *) set->data,
+ req->cidr);
-+
++
+ return ret;
+}
+
+static int
-+addip_kernel(struct ip_set *set,
++addip_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+{
+ struct ip_set_nethash *map = (struct ip_set_nethash *) set->data;
+ int ret = -ERANGE;
-+ ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC
++ ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr);
+#else
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr);
+#endif
-+
++
+ if (map->cidr[0])
+ ret = __addip(map, ip, map->cidr[0], hash_ip);
-+
++
+ return ret;
+}
+
+ u_int32_t i, hashsize = map->hashsize;
+ int res;
+ struct ip_set_nethash *tmp;
-+
++
+ if (map->resize == 0)
+ return -ERANGE;
+
+ again:
+ res = 0;
-+
++
+ /* Calculate new parameters */
+ hashsize += (hashsize * map->resize)/100;
+ if (hashsize == map->hashsize)
+ hashsize++;
-+
++
+ ip_set_printk("rehashing of set %s triggered: "
+ "hashsize grows from %u to %u",
+ set->name, map->hashsize, hashsize);
+
-+ tmp = kmalloc(sizeof(struct ip_set_nethash)
++ tmp = kmalloc(sizeof(struct ip_set_nethash)
+ + map->probes * sizeof(uint32_t), GFP_ATOMIC);
+ if (!tmp) {
+ DP("out of memory for %d bytes",
+ tmp->resize = map->resize;
+ memcpy(tmp->initval, map->initval, map->probes * sizeof(uint32_t));
+ memcpy(tmp->cidr, map->cidr, 30 * sizeof(unsigned char));
-+
++
+ write_lock_bh(&set->lock);
+ map = (struct ip_set_nethash *) set->data; /* Play safe */
+ for (i = 0; i < map->hashsize && res == 0; i++) {
-+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
++ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
+ if (*elem)
+ res = __addip_base(tmp, *elem);
+ }
+ kfree(tmp);
+ goto again;
+ }
-+
++
+ /* Success at resizing! */
+ members = map->members;
-+
++
+ map->hashsize = tmp->hashsize;
+ map->members = tmp->members;
+ write_unlock_bh(&set->lock);
+
+ if (!ip)
+ return -ERANGE;
-+
++
+ id = hash_id_cidr(map, ip, cidr, hash_ip);
+ if (id == UINT_MAX)
+ return -EEXIST;
-+
++
+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
+ *elem = 0;
+ map->elements--;
+ size);
+ return -EINVAL;
+ }
-+ /* TODO: no garbage collection in map->cidr */
-+ return __delip((struct ip_set_nethash *) set->data,
++ /* TODO: no garbage collection in map->cidr */
++ return __delip((struct ip_set_nethash *) set->data,
+ req->ip, req->cidr, hash_ip);
+}
+
+static int
-+delip_kernel(struct ip_set *set,
++delip_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+{
+ struct ip_set_nethash *map = (struct ip_set_nethash *) set->data;
+ int ret = -ERANGE;
-+ ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC
++ ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-+ ? ip_hdr(skb)->saddr
++ ? ip_hdr(skb)->saddr
+ : ip_hdr(skb)->daddr);
+#else
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr);
+#endif
-+
++
+ if (map->cidr[0])
+ ret = __delip(map, ip, map->cidr[0], hash_ip);
-+
++
+ return ret;
+}
+
+ kfree(map);
+ return -ENOMEM;
+ }
-+
++
+ set->data = map;
+ return 0;
+}
+ ip_set_ip_t i, *elem;
+
+ for (i = 0; i < map->hashsize; i++) {
-+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
++ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
+ ((ip_set_ip_t *)data)[i] = *elem;
+ }
+}
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
++ * published by the Free Software Foundation.
+ */
+
+/* Kernel module implementing a port set type as a bitmap */
+ switch (iph->protocol) {
+ case IPPROTO_TCP: {
+ struct tcphdr tcph;
-+
++
+ /* See comments at tcp_match in ip_tables.c */
+ if (offset)
+ return INVALID_PORT;
+#endif
+ /* No choice either */
+ return INVALID_PORT;
-+
++
+ return ntohs(flags & IPSET_SRC ?
+ tcph.source : tcph.dest);
+ }
+#endif
+ /* No choice either */
+ return INVALID_PORT;
-+
++
+ return ntohs(flags & IPSET_SRC ?
+ udph.source : udph.dest);
+ }
+
+ if (port < map->first_port || port > map->last_port)
+ return -ERANGE;
-+
++
+ *hash_port = port;
+ DP("set: %s, port:%u, %u", set->name, port, *hash_port);
+ return !!test_bit(port - map->first_port, map->members);
+testport(struct ip_set *set, const void *data, size_t size,
+ ip_set_ip_t *hash_port)
+{
-+ struct ip_set_req_portmap *req =
++ struct ip_set_req_portmap *req =
+ (struct ip_set_req_portmap *) data;
+
+ if (size != sizeof(struct ip_set_req_portmap)) {
+}
+
+static int
-+testport_kernel(struct ip_set *set,
++testport_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_port,
+ const u_int32_t *flags,
+ int res;
+ ip_set_ip_t port = get_port(skb, flags[index]);
+
-+ DP("flag %s port %u", flags[index] & IPSET_SRC ? "SRC" : "DST", port);
++ DP("flag %s port %u", flags[index] & IPSET_SRC ? "SRC" : "DST", port);
+ if (port == INVALID_PORT)
-+ return 0;
++ return 0;
+
+ res = __testport(set, port, hash_port);
-+
++
+ return (res < 0 ? 0 : res);
+}
+
+ return -ERANGE;
+ if (test_and_set_bit(port - map->first_port, map->members))
+ return -EEXIST;
-+
++
+ *hash_port = port;
+ DP("port %u", port);
+ return 0;
+addport(struct ip_set *set, const void *data, size_t size,
+ ip_set_ip_t *hash_port)
+{
-+ struct ip_set_req_portmap *req =
++ struct ip_set_req_portmap *req =
+ (struct ip_set_req_portmap *) data;
+
+ if (size != sizeof(struct ip_set_req_portmap)) {
+}
+
+static int
-+addport_kernel(struct ip_set *set,
++addport_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_port,
+ const u_int32_t *flags,
+ unsigned char index)
+{
+ ip_set_ip_t port = get_port(skb, flags[index]);
-+
++
+ if (port == INVALID_PORT)
+ return -EINVAL;
+
+ return -ERANGE;
+ if (!test_and_clear_bit(port - map->first_port, map->members))
+ return -EEXIST;
-+
++
+ *hash_port = port;
+ DP("port %u", port);
+ return 0;
+}
+
+static int
-+delport_kernel(struct ip_set *set,
++delport_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_port,
+ const u_int32_t *flags,
+ unsigned char index)
+{
+ ip_set_ip_t port = get_port(skb, flags[index]);
-+
++
+ if (port == INVALID_PORT)
+ return -EINVAL;
+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
++ * published by the Free Software Foundation.
+ */
+
+/* Kernel module to match an IP set. */
+match_set(const struct ipt_set_info *info,
+ const struct sk_buff *skb,
+ int inv)
-+{
++{
+ if (ip_set_testip_kernel(info->index, skb, info->flags))
+ inv = !inv;
+ return inv;
+#endif
+{
+ const struct ipt_set_info_match *info = matchinfo;
-+
++
+ return match_set(&info->match_set,
+ skb,
+ info->match_set.flags[0] & IPSET_MATCH_INV);
+#endif
+ unsigned int hook_mask)
+{
-+ struct ipt_set_info_match *info =
++ struct ipt_set_info_match *info =
+ (struct ipt_set_info_match *) matchinfo;
+ ip_set_id_t index;
+
+#endif
+
+ index = ip_set_get_byindex(info->match_set.index);
-+
++
+ if (index == IP_SET_INVALID_ID) {
+ ip_set_printk("Cannot find set indentified by id %u to match",
+ info->match_set.index);
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
++ * published by the Free Software Foundation.
+ */
+
+/* ipt_SET.c - netfilter target to manipulate IP sets */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ struct sk_buff *skb = *pskb;
+#endif
-+
++
+ if (info->add_set.index != IP_SET_INVALID_ID)
+ ip_set_addip_kernel(info->add_set.index,
+ skb,
+#endif
+ void *targinfo,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-+ unsigned int targinfosize,
++ unsigned int targinfosize,
+#endif
+ unsigned int hook_mask)
+{
-+ struct ipt_set_info_target *info =
++ struct ipt_set_info_target *info =
+ (struct ipt_set_info_target *) targinfo;
+ ip_set_id_t index;
+
+{
+ int count;
+
-+ wait_event_interruptible(random_write_wait,
++ wait_event_interruptible(random_write_wait,
+ input_pool.entropy_count < random_write_wakeup_thresh);
+
+ count = random_write_wakeup_thresh - input_pool.entropy_count;
+
+ /* likely we got woken up due to a signal */
-+ if (count <= 0) count = random_read_wakeup_thresh;
++ if (count <= 0) count = random_read_wakeup_thresh;
+
+ DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
+ count,
+
+ cd linux-2.4*; gunzip < ocf-linux-24-XXXXXXXX.patch.gz | patch -p1
+ cd linux-2.6*; gunzip < ocf-linux-26-XXXXXXXX.patch.gz | patch -p1
-+
++
+ if you do one of the above, then you can proceed to the next step,
+ or you can do the above process by hand with using the patches against
+ linux-2.4.35 and 2.6.23 to include the ocf code under crypto/ocf.
+ It should be easy to take this patch and apply it to other more
+ recent versions of the kernels. The same patches should also work
+ relatively easily on kernels as old as 2.6.11 and 2.4.18.
-+
++
+ * under 2.4 if you are on a non-x86 platform, you may need to:
+
+ cp linux-2.X.x/include/asm-i386/kmap_types.h linux-2.X.x/include/asm-YYY
+ * MAX_COMMAND = base command + mac command + encrypt command +
+ * mac-key + rc4-key
+ * MAX_RESULT = base result + mac result + mac + encrypt result
-+ *
++ *
+ *
+ */
+#define HIFN_MAX_COMMAND (8 + 8 + 8 + 64 + 260)
+
+
+/*********************************************************************
-+ * Structs for board commands
++ * Structs for board commands
+ *
+ *********************************************************************/
+
+
+ /*
+ * Our current positions for insertion and removal from the desriptor
-+ * rings.
++ * rings.
+ */
+ int cmdi, srci, dsti, resi;
+ volatile int cmdu, srcu, dstu, resu;
+ *
+ * session_num
+ * -----------
-+ * A number between 0 and 2048 (for DRAM models) or a number between
++ * A number between 0 and 2048 (for DRAM models) or a number between
+ * 0 and 768 (for SRAM models). Those who don't want to use session
+ * numbers should leave value at zero and send a new crypt key and/or
+ * new MAC key on every command. If you use session numbers and
+ * ----
+ * Either fill in the mbuf pointer and npa=0 or
+ * fill packp[] and packl[] and set npa to > 0
-+ *
++ *
+ * mac_header_skip
+ * ---------------
+ * The number of bytes of the source_buf that are skipped over before
+ * 0 for success, negative values on error
+ *
+ * Defines for negative error codes are:
-+ *
++ *
+ * HIFN_CRYPTO_BAD_INPUT : The passed in command had invalid settings.
+ * HIFN_CRYPTO_RINGS_FULL : All DMA rings were full and non-blocking
+ * behaviour was requested.
+ sc->sc_dmaier |= HIFN_DMAIER_PUBDONE;
+ WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
+#ifdef HIFN_VULCANDEV
-+ sc->sc_pkdev = make_dev(&vulcanpk_cdevsw, 0,
++ sc->sc_pkdev = make_dev(&vulcanpk_cdevsw, 0,
+ UID_ROOT, GID_WHEEL, 0666,
+ "vulcanpk");
+ sc->sc_pkdev->si_drv1 = sc;
+ * "hifn_enable_crypto" is called to enable it. The check is important,
+ * as enabling crypto twice will lock the board.
+ */
-+static int
++static int
+hifn_enable_crypto(struct hifn_softc *sc)
+{
+ u_int32_t dmacfg, ramcfg, encl, addr, i;
+ * Give initial values to the registers listed in the "Register Space"
+ * section of the HIFN Software Development reference manual.
+ */
-+static void
++static void
+hifn_init_pci_registers(struct hifn_softc *sc)
+{
+ DPRINTF("%s()\n", __FUNCTION__);
+/*
+ * Initialize the descriptor rings.
+ */
-+static void
++static void
+hifn_init_dma(struct hifn_softc *sc)
+{
+ struct hifn_dma *dma = sc->sc_dma;
+ dma->srci = idx;
+ dma->srcu += src->nsegs;
+ return (idx);
-+}
++}
+
+
-+static int
++static int
+hifn_crypto(
+ struct hifn_softc *sc,
+ struct hifn_command *cmd,
+ cmd->cklen = enccrd->crd_klen >> 3;
+ cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
+
-+ /*
++ /*
+ * Need to specify the size for the AES key in the masks.
+ */
+ if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) ==
+static ssize_t
+cryptoid_show(struct device *dev,
+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct hipp_softc *sc;
++ char *buf)
++{
++ struct hipp_softc *sc;
+
+ sc = pci_get_drvdata(to_pci_dev (dev));
+ return sprintf (buf, "%d\n", sc->sc_cid);
+ crypto_unregister_all(sc->sc_cid);
+ if (sc->sc_irq != -1)
+ free_irq(sc->sc_irq, sc);
-+
++
+#if 0
+ if (sc->sc_dma) {
+ /* Turn off DMA polling */
+ WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
+ HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
-+
++
+ pci_free_consistent(sc->sc_pcidev,
+ sizeof(*sc->sc_dma),
+ sc->sc_dma, sc->sc_dma_physaddr);
@@ -0,0 +1,93 @@
+/*
+ * Hifn HIPP-I/HIPP-II (7855/8155) driver.
-+ * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com> *
++ * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com> *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
++ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static void md5_calc(u_int8_t *, md5_ctxt *);
+ for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {
+ md5_calc((u_int8_t *)(input + i), ctxt);
+ }
-+
++
+ ctxt->md5_i = len - i;
+ bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i);
+ } else {
+{
+ u_int gap;
+
-+ /* Don't count up padding. Keep md5_n. */
++ /* Don't count up padding. Keep md5_n. */
+ gap = MD5_BUFLEN - ctxt->md5_i;
+ if (gap > 8) {
+ bcopy(md5_paddat,
+ MD5_BUFLEN - sizeof(ctxt->md5_n));
+ }
+
-+ /* 8 byte word */
++ /* 8 byte word */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8);
+#endif
+ u_int32_t D = ctxt->md5_std;
+#if BYTE_ORDER == LITTLE_ENDIAN
+ u_int32_t *X = (u_int32_t *)b64;
-+#endif
++#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ /* 4 byte words */
+ /* what a brute force but fast! */
+ ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);
+ ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);
+ ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);
-+
++
+ ROUND2(A, B, C, D, 1, Se, 17); ROUND2(D, A, B, C, 6, Sf, 18);
+ ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A, 0, Sh, 20);
+ ROUND2(A, B, C, D, 5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);
+ ROUND3(C, D, A, B, 3, Sk, 43); ROUND3(B, C, D, A, 6, Sl, 44);
+ ROUND3(A, B, C, D, 9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);
+ ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A, 2, Sl, 48);
-+
-+ ROUND4(A, B, C, D, 0, Sm, 49); ROUND4(D, A, B, C, 7, Sn, 50);
-+ ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A, 5, Sp, 52);
-+ ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C, 3, Sn, 54);
-+ ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A, 1, Sp, 56);
-+ ROUND4(A, B, C, D, 8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58);
-+ ROUND4(C, D, A, B, 6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60);
-+ ROUND4(A, B, C, D, 4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62);
++
++ ROUND4(A, B, C, D, 0, Sm, 49); ROUND4(D, A, B, C, 7, Sn, 50);
++ ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A, 5, Sp, 52);
++ ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C, 3, Sn, 54);
++ ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A, 1, Sp, 56);
++ ROUND4(A, B, C, D, 8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58);
++ ROUND4(C, D, A, B, 6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60);
++ ROUND4(A, B, C, D, 4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62);
+ ROUND4(C, D, A, B, 2, So, 63); ROUND4(B, C, D, A, 9, Sp, 64);
+
+ ctxt->md5_sta += A;
+ sc->sc_needwakeup &= ~wakeup;
+ crypto_unblock(sc->sc_cid, wakeup);
+ }
-+
++
+ return IRQ_HANDLED;
+}
+
+ /*
+ * Tell the hardware to copy the header to the output.
+ * The header is defined as the data from the end of
-+ * the bypass to the start of data to be encrypted.
++ * the bypass to the start of data to be encrypted.
+ * Typically this is the inline IV. Note that you need
+ * to do this even if src+dst are the same; it appears
+ * that w/o this bit the crypted data is written
+ * destination wil result in a
+ * destination particle list that does
+ * the necessary scatter DMA.
-+ */
++ */
+ safestats.st_iovnotuniform++;
+ err = EINVAL;
+ goto errout;
+ pci_unmap_operand(sc, &re->re_dst);
+ pci_unmap_operand(sc, &re->re_src);
+
-+ /*
++ /*
+ * If result was written to a differet mbuf chain, swap
+ * it in as the return value and reclaim the original.
+ */
+ */
+ re->re_sastate.sa_saved_indigest[0] =
+ cpu_to_be32(re->re_sastate.sa_saved_indigest[0]);
-+ re->re_sastate.sa_saved_indigest[1] =
++ re->re_sastate.sa_saved_indigest[1] =
+ cpu_to_be32(re->re_sastate.sa_saved_indigest[1]);
+ re->re_sastate.sa_saved_indigest[2] =
+ cpu_to_be32(re->re_sastate.sa_saved_indigest[2]);
+ } else {
+ re->re_sastate.sa_saved_indigest[0] =
+ cpu_to_le32(re->re_sastate.sa_saved_indigest[0]);
-+ re->re_sastate.sa_saved_indigest[1] =
++ re->re_sastate.sa_saved_indigest[1] =
+ cpu_to_le32(re->re_sastate.sa_saved_indigest[1]);
+ re->re_sastate.sa_saved_indigest[2] =
+ cpu_to_le32(re->re_sastate.sa_saved_indigest[2]);
+ * status reg in the read in case it is initialized. Then read
+ * the data register until it changes from the first read.
+ * Once it changes read the data register until it changes
-+ * again. At this time the RNG is considered initialized.
++ * again. At this time the RNG is considered initialized.
+ * This could take between 750ms - 1000ms in time.
+ */
+ i = 0;
+{
+ DPRINTF(("%s()\n", __FUNCTION__));
+
-+ WRITE_REG(sc, SAFE_RNG_CTRL,
++ WRITE_REG(sc, SAFE_RNG_CTRL,
+ READ_REG(sc, SAFE_RNG_CTRL) | SAFE_RNG_CTRL_SHORTEN);
+}
+
+ int i, rc;
+
+ DPRINTF(("%s()\n", __FUNCTION__));
-+
++
+ safestats.st_rng++;
+ /*
+ * Fetch the next block of data.
+#endif
+
+ crp = (struct cryptop *)re->re_crp;
-+
++
+ re->re_desc.d_csr = 0;
-+
++
+ crp->crp_etype = EFAULT;
+ crypto_done(crp);
+ return(0);
+ ((base_bits + 7) / 8) - 1;
+ modp = krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p +
+ ((mod_bits + 7) / 8) - 1;
-+
++
+ for (i = 0; i < (mod_bits + 7) / 8; i++, basep--, modp--) {
+ if (*modp < *basep)
+ goto too_small;
+#define SAFE_SA_CMD1_AES192 0x03000000 /* 192-bit AES key */
+#define SAFE_SA_CMD1_AES256 0x04000000 /* 256-bit AES key */
+
-+/*
++/*
+ * Security Associate State Record (Rev 1).
+ */
+struct safe_sastate {
+
+ /* XXX flush queues??? */
+
-+ /*
++ /*
+ * Reclaim dynamically allocated resources.
+ */
+ if (crypto_drivers != NULL)
+ * The Freescale SEC (also known as 'talitos') resides on the
+ * internal bus, and runs asynchronous to the processor core. It has
+ * a wide gamut of cryptographic acceleration features, including single-
-+ * pass IPsec (also known as algorithm chaining). To properly utilize
-+ * all of the SEC's performance enhancing features, further reworking
++ * pass IPsec (also known as algorithm chaining). To properly utilize
++ * all of the SEC's performance enhancing features, further reworking
+ * of higher level code (framework, applications) will be necessary.
+ *
+ * The following table shows which SEC version is present in which devices:
-+ *
++ *
+ * Devices SEC version
+ *
+ * 8272, 8248 SEC 1.0
+ *
+ * Channel ch0 may drive an aes operation to the aes unit (AESU),
+ * and, at the same time, ch1 may drive a message digest operation
-+ * to the mdeu. Each channel has an input descriptor FIFO, and the
++ * to the mdeu. Each channel has an input descriptor FIFO, and the
+ * FIFO can contain, e.g. on the 8541E, up to 24 entries, before a
+ * a buffer overrun error is triggered. The controller is responsible
-+ * for fetching the data from descriptor pointers, and passing the
-+ * data to the appropriate EUs. The controller also writes the
-+ * cryptographic operation's result to memory. The SEC notifies
-+ * completion by triggering an interrupt and/or setting the 1st byte
++ * for fetching the data from descriptor pointers, and passing the
++ * data to the appropriate EUs. The controller also writes the
++ * cryptographic operation's result to memory. The SEC notifies
++ * completion by triggering an interrupt and/or setting the 1st byte
+ * of the hdr field to 0xff.
+ *
+ * TODO:
+#include <cryptodev.h>
+#include <uio.h>
+
-+#define DRV_NAME "talitos"
++#define DRV_NAME "talitos"
+
+#include "talitos_dev.h"
+#include "talitos_soft.h"
+static int talitos_freesession(device_t dev, u_int64_t tid);
+static int talitos_process(device_t dev, struct cryptop *crp, int hint);
+static void dump_talitos_status(struct talitos_softc *sc);
-+static int talitos_submit(struct talitos_softc *sc, struct talitos_desc *td,
++static int talitos_submit(struct talitos_softc *sc, struct talitos_desc *td,
+ int chsel);
+static void talitos_doneprocessing(struct talitos_softc *sc);
+static void talitos_init_device(struct talitos_softc *sc);
+ v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
+ printk(KERN_INFO "%s: ISR 0x%08x_%08x\n",
+ device_get_nameunit(sc->sc_cdev), v, v_hi);
-+ for (i = 0; i < sc->sc_num_channels; i++) {
-+ v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
++ for (i = 0; i < sc->sc_num_channels; i++) {
++ v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
+ TALITOS_CH_CDPR);
-+ v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
++ v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
+ TALITOS_CH_CDPR_HI);
-+ printk(KERN_INFO "%s: CDPR ch%d 0x%08x_%08x\n",
++ printk(KERN_INFO "%s: CDPR ch%d 0x%08x_%08x\n",
+ device_get_nameunit(sc->sc_cdev), i, v, v_hi);
+ }
-+ for (i = 0; i < sc->sc_num_channels; i++) {
-+ v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
++ for (i = 0; i < sc->sc_num_channels; i++) {
++ v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
+ TALITOS_CH_CCPSR);
-+ v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
++ v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
+ TALITOS_CH_CCPSR_HI);
-+ printk(KERN_INFO "%s: CCPSR ch%d 0x%08x_%08x\n",
++ printk(KERN_INFO "%s: CCPSR ch%d 0x%08x_%08x\n",
+ device_get_nameunit(sc->sc_cdev), i, v, v_hi);
+ }
+ ptr = sc->sc_base_addr + TALITOS_CH_DESCBUF;
-+ for (i = 0; i < 16; i++) {
++ for (i = 0; i < 16; i++) {
+ v = talitos_read(ptr++); v_hi = talitos_read(ptr++);
-+ printk(KERN_INFO "%s: DESCBUF ch0 0x%08x_%08x (tdp%02d)\n",
++ printk(KERN_INFO "%s: DESCBUF ch0 0x%08x_%08x (tdp%02d)\n",
+ device_get_nameunit(sc->sc_cdev), v, v_hi, i);
+ }
+ return;
+
+
+#ifdef CONFIG_OCF_RANDOMHARVEST
-+/*
++/*
+ * pull random numbers off the RNG FIFO, not exceeding amount available
+ */
+static int
+ return 0;
+ }
+ /*
-+ * OFL is number of available 64-bit words,
++ * OFL is number of available 64-bit words,
+ * shift and convert to a 32-bit word count
+ */
+ v = talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI);
+ if (maxwords > v)
+ maxwords = v;
+ for (rc = 0; rc < maxwords; rc++) {
-+ buf[rc] = talitos_read(sc->sc_base_addr +
++ buf[rc] = talitos_read(sc->sc_base_addr +
+ TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
+ }
+ if (maxwords & 1) {
-+ /*
++ /*
+ * RNG will complain with an AE in the RNGISR
+ * if we don't complete the pairs of 32-bit reads
+ * to its 64-bit register based FIFO
+ */
-+ v = talitos_read(sc->sc_base_addr +
++ v = talitos_read(sc->sc_base_addr +
+ TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
+ }
+
+ v = talitos_read(sc->sc_base_addr + TALITOS_RNGRCR_HI);
+ v |= TALITOS_RNGRCR_HI_SR;
+ talitos_write(sc->sc_base_addr + TALITOS_RNGRCR_HI, v);
-+ while ((talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI)
++ while ((talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI)
+ & TALITOS_RNGSR_HI_RD) == 0)
+ cpu_relax();
+ /*
+ * we tell the RNG to start filling the RNG FIFO
-+ * by writing the RNGDSR
++ * by writing the RNGDSR
+ */
+ v = talitos_read(sc->sc_base_addr + TALITOS_RNGDSR_HI);
+ talitos_write(sc->sc_base_addr + TALITOS_RNGDSR_HI, v);
+ /*
-+ * 64 bits of data will be pushed onto the FIFO every
-+ * 256 SEC cycles until the FIFO is full. The RNG then
++ * 64 bits of data will be pushed onto the FIFO every
++ * 256 SEC cycles until the FIFO is full. The RNG then
+ * attempts to keep the FIFO full.
+ */
+ v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);
+ return;
+ }
+ /*
-+ * n.b. we need to add a FIPS test here - if the RNG is going
++ * n.b. we need to add a FIPS test here - if the RNG is going
+ * to fail, it's going to fail at reset time
+ */
+ return;
+ }
+ if (encini == NULL && macini == NULL)
+ return EINVAL;
-+ if (encini) {
++ if (encini) {
+ /* validate key length */
+ switch (encini->cri_alg) {
+ case CRYPTO_DES_CBC:
+ return EINVAL;
+ break;
+ default:
-+ DPRINTF("UNKNOWN encini->cri_alg %d\n",
++ DPRINTF("UNKNOWN encini->cri_alg %d\n",
+ encini->cri_alg);
+ return EINVAL;
+ }
+ /* allocating session */
+ sesn = sc->sc_nsessions;
+ ses = (struct talitos_session *) kmalloc(
-+ (sesn + 1) * sizeof(struct talitos_session),
++ (sesn + 1) * sizeof(struct talitos_session),
+ SLAB_ATOMIC);
+ if (ses == NULL)
+ return ENOMEM;
+ memset(ses, 0,
+ (sesn + 1) * sizeof(struct talitos_session));
-+ memcpy(ses, sc->sc_sessions,
++ memcpy(ses, sc->sc_sessions,
+ sesn * sizeof(struct talitos_session));
+ memset(sc->sc_sessions, 0,
+ sesn * sizeof(struct talitos_session));
+ }
+ }
+
-+ /* really should make up a template td here,
++ /* really should make up a template td here,
+ * and only fill things like i/o and direction in process() */
+
+ /* assign session ID */
+}
+
+/*
-+ * launch device processing - it will come back with done notification
-+ * in the form of an interrupt and/or HDR_DONE_BITS in header
++ * launch device processing - it will come back with done notification
++ * in the form of an interrupt and/or HDR_DONE_BITS in header
+ */
-+static int
++static int
+talitos_submit(
+ struct talitos_softc *sc,
+ struct talitos_desc *td,
+ u_int32_t v;
+
+ v = dma_map_single(NULL, td, sizeof(*td), DMA_TO_DEVICE);
-+ talitos_write(sc->sc_base_addr +
++ talitos_write(sc->sc_base_addr +
+ chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF, 0);
-+ talitos_write(sc->sc_base_addr +
++ talitos_write(sc->sc_base_addr +
+ chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF_HI, v);
+ return 0;
+}
+ struct talitos_desc *td;
+ unsigned long flags;
+ /* descriptor mappings */
-+ int hmac_key, hmac_data, cipher_iv, cipher_key,
++ int hmac_key, hmac_data, cipher_iv, cipher_key,
+ in_fifo, out_fifo, cipher_iv_out;
+ static int chsel = -1;
+
+
+ ses = &sc->sc_sessions[TALITOS_SESSION(crp->crp_sid)];
+
-+ /* enter the channel scheduler */
++ /* enter the channel scheduler */
+ spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
+
+ /* reuse channel that already had/has requests for the required EU */
+ /*
+ * haven't seen this algo the last sc_num_channels or more
+ * use round robin in this case
-+ * nb: sc->sc_num_channels must be power of 2
++ * nb: sc->sc_num_channels must be power of 2
+ */
+ chsel = (chsel + 1) & (sc->sc_num_channels - 1);
+ } else {
+ /*
-+ * matches channel with same target execution unit;
++ * matches channel with same target execution unit;
+ * use same channel in this case
+ */
+ chsel = i;
+ }
+ sc->sc_chnlastalg[chsel] = crp->crp_desc->crd_alg;
+
-+ /* release the channel scheduler lock */
++ /* release the channel scheduler lock */
+ spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
+
+ /* acquire the selected channel fifo lock */
+ /* find and reserve next available descriptor-cryptop pair */
+ for (i = 0; i < sc->sc_chfifo_len; i++) {
+ if (sc->sc_chnfifo[chsel][i].cf_desc.hdr == 0) {
-+ /*
++ /*
+ * ensure correct descriptor formation by
+ * avoiding inadvertently setting "optional" entries
+ * e.g. not using "optional" dptr2 for MD/HMAC descs
+ memset(&sc->sc_chnfifo[chsel][i].cf_desc,
+ 0, sizeof(*td));
+ /* reserve it with done notification request bit */
-+ sc->sc_chnfifo[chsel][i].cf_desc.hdr |=
++ sc->sc_chnfifo[chsel][i].cf_desc.hdr |=
+ TALITOS_DONE_NOTIFY;
+ break;
+ }
+ err = ERESTART;
+ goto errout;
+ }
-+
++
+ td = &sc->sc_chnfifo[chsel][i].cf_desc;
+ sc->sc_chnfifo[chsel][i].cf_crp = crp;
+
+ err = EINVAL;
+ goto errout;
+ }
-+ td->ptr[in_fifo].ptr = dma_map_single(NULL, skb->data,
++ td->ptr[in_fifo].ptr = dma_map_single(NULL, skb->data,
+ skb->len, DMA_TO_DEVICE);
+ td->ptr[in_fifo].len = skb->len;
-+ td->ptr[out_fifo].ptr = dma_map_single(NULL, skb->data,
++ td->ptr[out_fifo].ptr = dma_map_single(NULL, skb->data,
+ skb->len, DMA_TO_DEVICE);
+ td->ptr[out_fifo].len = skb->len;
+ td->ptr[hmac_data].ptr = dma_map_single(NULL, skb->data,
+ * copy both the header+IV.
+ */
+ if (enccrd->crd_flags & CRD_F_ENCRYPT) {
-+ td->hdr |= TALITOS_DIR_OUTBOUND;
++ td->hdr |= TALITOS_DIR_OUTBOUND;
+ if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
+ iv = enccrd->crd_iv;
+ else
+ enccrd->crd_inject, ivsize, iv);
+ }
+ } else {
-+ td->hdr |= TALITOS_DIR_INBOUND;
++ td->hdr |= TALITOS_DIR_INBOUND;
+ if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
+ iv = enccrd->crd_iv;
+ bcopy(enccrd->crd_iv, iv, ivsize);
+ enccrd->crd_inject, ivsize, iv);
+ }
+ }
-+ td->ptr[cipher_iv].ptr = dma_map_single(NULL, iv, ivsize,
++ td->ptr[cipher_iv].ptr = dma_map_single(NULL, iv, ivsize,
+ DMA_TO_DEVICE);
+ td->ptr[cipher_iv].len = ivsize;
+ /*
+ | TALITOS_MODE1_MDEU_INIT
+ | TALITOS_MODE1_MDEU_PAD;
+ switch (maccrd->crd_alg) {
-+ case CRYPTO_MD5:
++ case CRYPTO_MD5:
+ td->hdr |= TALITOS_MODE1_MDEU_MD5;
+ break;
-+ case CRYPTO_MD5_HMAC:
++ case CRYPTO_MD5_HMAC:
+ td->hdr |= TALITOS_MODE1_MDEU_MD5_HMAC;
+ break;
-+ case CRYPTO_SHA1:
++ case CRYPTO_SHA1:
+ td->hdr |= TALITOS_MODE1_MDEU_SHA1;
+ break;
-+ case CRYPTO_SHA1_HMAC:
++ case CRYPTO_SHA1_HMAC:
+ td->hdr |= TALITOS_MODE1_MDEU_SHA1_HMAC;
+ break;
+ default:
+ * crypt data is the difference in the skips.
+ */
+ /* ipsec only for now */
-+ td->ptr[hmac_key].ptr = dma_map_single(NULL,
++ td->ptr[hmac_key].ptr = dma_map_single(NULL,
+ ses->ses_hmac, ses->ses_hmac_len, DMA_TO_DEVICE);
+ td->ptr[hmac_key].len = ses->ses_hmac_len;
+ td->ptr[in_fifo].ptr += enccrd->crd_skip;
+ td->ptr[out_fifo].len = enccrd->crd_len;
+ /* bytes of HMAC to postpend to ciphertext */
+ td->ptr[out_fifo].extent = ses->ses_mlen;
-+ td->ptr[hmac_data].ptr += maccrd->crd_skip;
++ td->ptr[hmac_data].ptr += maccrd->crd_skip;
+ td->ptr[hmac_data].len = enccrd->crd_skip - maccrd->crd_skip;
+ }
+ if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
+ | TALITOS_MODE0_MDEU_INIT
+ | TALITOS_MODE0_MDEU_PAD;
+ switch (maccrd->crd_alg) {
-+ case CRYPTO_MD5:
++ case CRYPTO_MD5:
+ td->hdr |= TALITOS_MODE0_MDEU_MD5;
+ DPRINTF("MD5 ses %d ch %d len %d\n",
-+ (u32)TALITOS_SESSION(crp->crp_sid),
++ (u32)TALITOS_SESSION(crp->crp_sid),
+ chsel, td->ptr[in_fifo].len);
+ break;
-+ case CRYPTO_MD5_HMAC:
++ case CRYPTO_MD5_HMAC:
+ td->hdr |= TALITOS_MODE0_MDEU_MD5_HMAC;
+ break;
-+ case CRYPTO_SHA1:
++ case CRYPTO_SHA1:
+ td->hdr |= TALITOS_MODE0_MDEU_SHA1;
+ DPRINTF("SHA1 ses %d ch %d len %d\n",
-+ (u32)TALITOS_SESSION(crp->crp_sid),
++ (u32)TALITOS_SESSION(crp->crp_sid),
+ chsel, td->ptr[in_fifo].len);
+ break;
-+ case CRYPTO_SHA1_HMAC:
++ case CRYPTO_SHA1_HMAC:
+ td->hdr |= TALITOS_MODE0_MDEU_SHA1_HMAC;
+ break;
+ default:
+
+ if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||
+ (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {
-+ td->ptr[hmac_key].ptr = dma_map_single(NULL,
-+ ses->ses_hmac, ses->ses_hmac_len,
++ td->ptr[hmac_key].ptr = dma_map_single(NULL,
++ ses->ses_hmac, ses->ses_hmac_len,
+ DMA_TO_DEVICE);
+ td->ptr[hmac_key].len = ses->ses_hmac_len;
+ }
-+ }
++ }
+ else {
+ /* using process key (session data has duplicate) */
-+ td->ptr[cipher_key].ptr = dma_map_single(NULL,
-+ enccrd->crd_key, (enccrd->crd_klen + 7) / 8,
++ td->ptr[cipher_key].ptr = dma_map_single(NULL,
++ enccrd->crd_key, (enccrd->crd_klen + 7) / 8,
+ DMA_TO_DEVICE);
+ td->ptr[cipher_key].len = (enccrd->crd_klen + 7) / 8;
+ }
+ return err;
+}
+
-+/* go through all channels descriptors, notifying OCF what has
-+ * _and_hasn't_ successfully completed and reset the device
++/* go through all channels descriptors, notifying OCF what has
++ * _and_hasn't_ successfully completed and reset the device
+ * (otherwise it's up to decoding desc hdrs!)
+ */
+static void talitos_errorprocessing(struct talitos_softc *sc)
+ spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
+
+ if (debug) dump_talitos_status(sc);
-+ /* go through descriptors, try and salvage those successfully done,
++ /* go through descriptors, try and salvage those successfully done,
+ * and EIO those that weren't
+ */
+ for (i = 0; i < sc->sc_num_channels; i++) {
+ spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
+ for (j = 0; j < sc->sc_chfifo_len; j++) {
+ if (sc->sc_chnfifo[i][j].cf_desc.hdr) {
-+ if ((sc->sc_chnfifo[i][j].cf_desc.hdr
-+ & TALITOS_HDR_DONE_BITS)
++ if ((sc->sc_chnfifo[i][j].cf_desc.hdr
++ & TALITOS_HDR_DONE_BITS)
+ != TALITOS_HDR_DONE_BITS) {
+ /* this one didn't finish */
+ /* signify in crp->etype */
-+ sc->sc_chnfifo[i][j].cf_crp->crp_etype
++ sc->sc_chnfifo[i][j].cf_crp->crp_etype
+ = EIO;
+ }
+ } else
+ spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
+ for (j = 0; j < sc->sc_chfifo_len; j++) {
+ /* descriptor has done bits set? */
-+ if ((sc->sc_chnfifo[i][j].cf_desc.hdr
-+ & TALITOS_HDR_DONE_BITS)
++ if ((sc->sc_chnfifo[i][j].cf_desc.hdr
++ & TALITOS_HDR_DONE_BITS)
+ == TALITOS_HDR_DONE_BITS) {
+ /* notify ocf */
+ crypto_done(sc->sc_chnfifo[i][j].cf_crp);
+{
+ struct talitos_softc *sc = arg;
+ u_int32_t v, v_hi;
-+
++
+ /* ack */
+ v = talitos_read(sc->sc_base_addr + TALITOS_ISR);
+ v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
+
+ /* init all channels */
+ for (i = 0; i < sc->sc_num_channels; i++) {
-+ v = talitos_read(sc->sc_base_addr +
++ v = talitos_read(sc->sc_base_addr +
+ i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI);
+ v |= TALITOS_CH_CCCR_HI_CDWE
+ | TALITOS_CH_CCCR_HI_CDIE; /* invoke interrupt if done */
-+ talitos_write(sc->sc_base_addr +
++ talitos_write(sc->sc_base_addr +
+ i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI, v);
+ }
+ /* enable all interrupts */
+
+ /*
+ * Master reset
-+ * errata documentation: warning: certain SEC interrupts
-+ * are not fully cleared by writing the MCR:SWR bit,
-+ * set bit twice to completely reset
++ * errata documentation: warning: certain SEC interrupts
++ * are not fully cleared by writing the MCR:SWR bit,
++ * set bit twice to completely reset
+ */
+ talitos_reset_device_master(sc); /* once */
+ talitos_reset_device_master(sc); /* and once again */
-+
++
+ /* reset all channels */
+ for (i = 0; i < sc->sc_num_channels; i++) {
+ v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
+ rc = request_irq(sc->sc_irq, talitos_intr, 0,
+ device_get_nameunit(sc->sc_cdev), sc);
+ if (rc) {
-+ printk(KERN_ERR "%s: failed to hook irq %d\n",
++ printk(KERN_ERR "%s: failed to hook irq %d\n",
+ device_get_nameunit(sc->sc_cdev), sc->sc_irq);
+ sc->sc_irq = -1;
+ goto out;
+ memset(sc->sc_chnlastalg, 0, sc->sc_num_channels * sizeof(int));
+
+ sc->sc_chnfifo = (struct desc_cryptop_pair **) kmalloc(
-+ sc->sc_num_channels * sizeof(struct desc_cryptop_pair *),
++ sc->sc_num_channels * sizeof(struct desc_cryptop_pair *),
+ GFP_KERNEL);
+ if (!sc->sc_chnfifo)
+ goto out;
+ for (i = 0; i < sc->sc_num_channels; i++) {
+ sc->sc_chnfifo[i] = (struct desc_cryptop_pair *) kmalloc(
-+ sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair),
++ sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair),
+ GFP_KERNEL);
+ if (!sc->sc_chnfifo[i])
+ goto out;
-+ memset(sc->sc_chnfifo[i], 0,
++ memset(sc->sc_chnfifo[i], 0,
+ sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair));
+ }
+
+#define TALITOS_ID_SEC_2_1 0x40 /* cross ref with IP block revision reg */
+
+/*
-+ * following num_channels, channel-fifo-depth, exec-unit-mask, and
++ * following num_channels, channel-fifo-depth, exec-unit-mask, and
+ * descriptor-types-mask are for forward-compatibility with openfirmware
+ * flat device trees
+ */
+#define TALITOS_CHFIFOLEN_SEC_2_1 24
+#define TALITOS_CHFIFOLEN_SEC_2_4 24
+
-+/*
++/*
+ * exec-unit-mask : The bitmask representing what Execution Units (EUs)
-+ * are available. EU information should be encoded following the SEC's
++ * are available. EU information should be encoded following the SEC's
+ * EU_SEL0 bitfield documentation, i.e. as follows:
-+ *
++ *
+ * bit 31 = set if SEC permits no-EU selection (should be always set)
+ * bit 30 = set if SEC has the ARC4 EU (AFEU)
+ * bit 29 = set if SEC has the des/3des EU (DEU)
+ * bit 26 = set if SEC has the public key EU (PKEU)
+ * bit 25 = set if SEC has the aes EU (AESU)
+ * bit 24 = set if SEC has the Kasumi EU (KEU)
-+ *
++ *
+ */
+#define TALITOS_HAS_EU_NONE (1<<0)
+#define TALITOS_HAS_EU_AFEU (1<<1)
+
+/*
+ * descriptor-types-mask : The bitmask representing what descriptors
-+ * are available. Descriptor type information should be encoded
-+ * following the SEC's Descriptor Header Dword DESC_TYPE field
++ * are available. Descriptor type information should be encoded
++ * following the SEC's Descriptor Header Dword DESC_TYPE field
+ * documentation, i.e. as follows:
+ *
+ * bit 0 = set if SEC supports the aesu_ctr_nonsnoop desc. type
+#define TALITOS_HAS_DESCTYPES_SEC_2_0 0x01010ebf
+#define TALITOS_HAS_DESCTYPES_SEC_2_1 0x012b0ebf
+
-+/*
++/*
+ * a TALITOS_xxx_HI address points to the low data bits (32-63) of the register
+ */
+
+#define TALITOS_CH_FF_HI 0x114c /* Fetch FIFO's FETCH_ADRS */
+#define TALITOS_CH_CDPR 0x1140 /* Crypto-Channel Pointer Status Reg */
+#define TALITOS_CH_CDPR_HI 0x1144 /* Crypto-Channel Pointer Status Reg */
-+#define TALITOS_CH_DESCBUF 0x1180 /* (thru 11bf) Crypto-Channel
++#define TALITOS_CH_DESCBUF 0x1180 /* (thru 11bf) Crypto-Channel
+ * Descriptor Buffer (debug) */
+
+/* execution unit register offset addresses and bits */
+#endif
+ }
+ }
-+
++
+ kfree(buf);
+
+bad_alloc:
+ IX_MBUF_MLEN(&q->ixp_q_mbuf) = IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) =
+ ((IX_MBUF_MLEN(&q->ixp_q_mbuf) * 8) + 72 + 511) / 8;
+ tbuf = kmalloc(IX_MBUF_MLEN(&q->ixp_q_mbuf), SLAB_ATOMIC);
-+
++
+ if (IX_MBUF_MDATA(&q->ixp_q_mbuf) == NULL) {
+ printk("ixp: kmalloc(%u, SLAB_ATOMIC) failed\n",
+ IX_MBUF_MLEN(&q->ixp_q_mbuf));
+ &q->pkq_op,
+ ixp_kperform_cb,
+ &q->pkq_result);
-+
++
+ if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {
+ dprintk("%s() - ixCryptoAccPkeEauPerform SUCCESS\n", __FUNCTION__);
+ return; /* callback will return here for callback */
+ int hid = crid & ~(CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
+ int typ = crid & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
+ int caps = 0;
-+
++
+ /* if the user hasn't selected a driver, then just call newsession */
+ if (hid == 0 && typ != 0)
+ return 0;
+ dprintk("%s: hid=%x typ=%x not matched\n", __FUNCTION__, hid, typ);
+ return EINVAL;
+ }
-+
++
+ /* the user didn't specify SW or HW, so the driver is ok */
+ if (typ == 0)
+ return 0;
+ } while ((krp->krp_flags & CRYPTO_KF_DONE) == 0);
+
+ dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
-+
++
+ kop->crk_crid = krp->krp_crid; /* device that did the work */
+ if (krp->krp_status != 0) {
+ error = krp->krp_status;
+ }
+ return (0);
+}
-+
++
+static struct csession *
+cseadd(struct fcrypt *fcr, struct csession *cse)
+{
+ int mackeylen; /* mac key */
+ caddr_t mackey;
+
-+ u_int32_t ses; /* returns: session # */
++ u_int32_t ses; /* returns: session # */
+};
+
+struct session2_op {
+ int mackeylen; /* mac key */
+ caddr_t mackey;
+
-+ u_int32_t ses; /* returns: session # */
++ u_int32_t ses; /* returns: session # */
+ int crid; /* driver id + flags (rw) */
+ int pad[4]; /* for future expansion */
+};
+ * since it does no crypto at all.
+ *
+ * Written by David McCullough <david_mccullough@securecomputing.com>
-+ * Copyright (C) 2006-2007 David McCullough
++ * Copyright (C) 2006-2007 David McCullough
+ *
+ * LICENSE TERMS
+ *
+ offset_in_page(uiop->uio_iov[sg_num].iov_base+skip));
+ sg_len += len;
+ skip = 0;
-+ } else
++ } else
+ skip -= uiop->uio_iov[sg_num].iov_len;
+ }
+ } else {
+ case SW_TYPE_BLKCIPHER: {
+ unsigned char iv[EALG_MAX_BLOCK_LEN];
+ unsigned char *ivp = iv;
-+ int ivsize =
++ int ivsize =
+ crypto_blkcipher_ivsize(crypto_blkcipher_cast(sw->sw_tfm));
+ struct blkcipher_desc desc;
+
+ sw->u.hmac.sw_klen);
+ crypto_hash_digest(&desc, sg, sg_len, result);
+#endif /* #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
-+
++
+ } else { /* SW_TYPE_HASH */
+ crypto_hash_digest(&desc, sg, sg_len, result);
+ }
+
+ for (i = CRYPTO_ALGORITHM_MIN; i <= CRYPTO_ALGORITHM_MAX; ++i)
+ {
-+
++
+ algo = crypto_details[i].alg_name;
+ if (!algo || !*algo)
+ {