summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPhoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de>2014-05-16 17:46:45 +0200
committerDavid S. Miller <davem@davemloft.net>2014-05-16 17:23:42 -0400
commitf0f77dc6be76ed1854b08688390e156e4b351ab5 (patch)
tree07e7cdba0bc3a096bf2933da0a1af984e6ae4dd2 /net
parent3e9c156e2c210ab67b12b1b692983a6b97c19d3f (diff)
downloadlinux-f0f77dc6be76ed1854b08688390e156e4b351ab5.tar.bz2
ieee802154, mac802154: implement devkey record option
The 802.15.4-2011 standard states that for each key, a list of devices that use this key shall be kept. Previous patches have only considered two options: * a device "uses" (or may use) all keys, rendering the list useless * a device is restricted to a certain set of keys Another option would be that a device *may* use all keys, but need not do so, and we are interested in the actual set of keys the device uses. Recording keys used by any given device may have a noticable performance impact and might not be needed as often. The common case, in which a device will not switch keys too often, should still perform well. Signed-off-by: Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/mac802154/llsec.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/net/mac802154/llsec.c b/net/mac802154/llsec.c
index 392653b1b5a3..a83674edaafd 100644
--- a/net/mac802154/llsec.c
+++ b/net/mac802154/llsec.c
@@ -921,6 +921,37 @@ llsec_do_decrypt(struct sk_buff *skb, const struct mac802154_llsec *sec,
}
static int
+llsec_update_devkey_record(struct mac802154_llsec_device *dev,
+ const struct ieee802154_llsec_key_id *in_key)
+{
+ struct mac802154_llsec_device_key *devkey;
+
+ devkey = llsec_devkey_find(dev, in_key);
+
+ if (!devkey) {
+ struct mac802154_llsec_device_key *next;
+
+ next = kzalloc(sizeof(*devkey), GFP_ATOMIC);
+ if (!next)
+ return -ENOMEM;
+
+ next->devkey.key_id = *in_key;
+
+ spin_lock_bh(&dev->lock);
+
+ devkey = llsec_devkey_find(dev, in_key);
+ if (!devkey)
+ list_add_rcu(&next->devkey.list, &dev->dev.keys);
+ else
+ kfree(next);
+
+ spin_unlock_bh(&dev->lock);
+ }
+
+ return 0;
+}
+
+static int
llsec_update_devkey_info(struct mac802154_llsec_device *dev,
const struct ieee802154_llsec_key_id *in_key,
u32 frame_counter)
@@ -933,6 +964,13 @@ llsec_update_devkey_info(struct mac802154_llsec_device *dev,
return -ENOENT;
}
+ if (dev->dev.key_mode == IEEE802154_LLSEC_DEVKEY_RECORD) {
+ int rc = llsec_update_devkey_record(dev, in_key);
+
+ if (rc < 0)
+ return rc;
+ }
+
spin_lock_bh(&dev->lock);
if ((!devkey && frame_counter < dev->dev.frame_counter) ||