diff options
author | Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de> | 2014-05-16 17:46:45 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-05-16 23:23:42 +0200 |
commit | f0f77dc6be76ed1854b08688390e156e4b351ab5 (patch) | |
tree | 07e7cdba0bc3a096bf2933da0a1af984e6ae4dd2 | |
parent | ieee802154: add netlink interfaces for llsec (diff) | |
download | linux-f0f77dc6be76ed1854b08688390e156e4b351ab5.tar.xz linux-f0f77dc6be76ed1854b08688390e156e4b351ab5.zip |
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>
-rw-r--r-- | include/net/ieee802154_netdev.h | 1 | ||||
-rw-r--r-- | net/mac802154/llsec.c | 38 |
2 files changed, 39 insertions, 0 deletions
diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index eb9f850a51b6..3b53c8e405e4 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 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) || |