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.buckheis...@itwm.fraunhofer.de>
---
 include/net/ieee802154_netdev.h |    1 +
 net/mac802154/llsec.c           |   41 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
index 38988e4..caae174 100644
--- a/include/net/ieee802154_netdev.h
+++ b/include/net/ieee802154_netdev.h
@@ -280,6 +280,7 @@ struct ieee802154_llsec_device_key {
 enum {
        IEEE802154_LLSEC_DEVKEY_IGNORE,
        IEEE802154_LLSEC_DEVKEY_RESTRICT,
+       IEEE802154_LLSEC_DEVKEY_RECORD,
 
        __IEEE802154_LLSEC_DEVKEY_MAX,
 };
diff --git a/net/mac802154/llsec.c b/net/mac802154/llsec.c
index d487606..dee5c06 100644
--- a/net/mac802154/llsec.c
+++ b/net/mac802154/llsec.c
@@ -876,12 +876,44 @@ llsec_do_decrypt(struct sk_buff *skb,
 }
 
 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;
+       unsigned long flags;
+
+       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_irqsave(&dev->lock, flags);
+
+               devkey = llsec_devkey_find(dev, in_key);
+               if (!devkey)
+                       list_add_rcu(&next->devkey.list, &dev->dev.keys);
+               else
+                       kfree(next);
+
+               spin_unlock_irqrestore(&dev->lock, flags);
+       }
+
+       return 0;
+}
+
+static int
 llsec_update_devkey_info(struct mac802154_llsec_device *dev,
                         const struct ieee802154_llsec_key_id *in_key,
                         u32 frame_counter)
 {
        struct mac802154_llsec_device_key *devkey = NULL;
-       unsigned int flags;
+       unsigned long flags;
 
        if (dev->dev.key_mode == IEEE802154_LLSEC_DEVKEY_RESTRICT) {
                devkey = llsec_devkey_find(dev, in_key);
@@ -889,6 +921,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_irqsave(&dev->lock, flags);
 
        if ((!devkey && frame_counter < dev->dev.frame_counter) ||
-- 
1.7.9.5


------------------------------------------------------------------------------
Is your legacy SCM system holding you back? Join Perforce May 7 to find out:
&#149; 3 signs your SCM is hindering your productivity
&#149; Requirements for releasing software faster
&#149; Expert tips and advice for migrating your SCM now
http://p.sf.net/sfu/perforce
_______________________________________________
Linux-zigbee-devel mailing list
Linux-zigbee-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-zigbee-devel

Reply via email to