Signed-off-by: Phoebe Buckheister <phoebe.buckheis...@itwm.fraunhofer.de>
---
 include/linux/nl802154.h    |    3 ++
 net/ieee802154/ieee802154.h |    4 ++
 net/ieee802154/netlink.c    |    4 ++
 net/ieee802154/nl-mac.c     |  114 ++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 124 insertions(+), 1 deletion(-)

diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h
index a31e747..e2ca843 100644
--- a/include/linux/nl802154.h
+++ b/include/linux/nl802154.h
@@ -155,6 +155,9 @@ enum {
        IEEE802154_LLSEC_LIST_DEV,
        IEEE802154_LLSEC_ADD_DEV,
        IEEE802154_LLSEC_DEL_DEV,
+       IEEE802154_LLSEC_LIST_DEVKEY,
+       IEEE802154_LLSEC_ADD_DEVKEY,
+       IEEE802154_LLSEC_DEL_DEVKEY,
 
        __IEEE802154_CMD_MAX,
 };
diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h
index 5f410ca..484a20b 100644
--- a/net/ieee802154/ieee802154.h
+++ b/net/ieee802154/ieee802154.h
@@ -78,5 +78,9 @@ int ieee802154_llsec_add_dev(struct sk_buff *skb, struct 
genl_info *info);
 int ieee802154_llsec_del_dev(struct sk_buff *skb, struct genl_info *info);
 int ieee802154_llsec_dump_devs(struct sk_buff *skb,
                               struct netlink_callback *cb);
+int ieee802154_llsec_add_devkey(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_llsec_del_devkey(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_llsec_dump_devkeys(struct sk_buff *skb,
+                                 struct netlink_callback *cb);
 
 #endif
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 63cd851..86e33e5 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -134,6 +134,10 @@ static const struct genl_ops ieee8021154_ops[] = {
                        ieee802154_llsec_dump_devs),
        IEEE802154_OP(IEEE802154_LLSEC_ADD_DEV, ieee802154_llsec_add_dev),
        IEEE802154_OP(IEEE802154_LLSEC_DEL_DEV, ieee802154_llsec_del_dev),
+       IEEE802154_DUMP(IEEE802154_LLSEC_LIST_DEVKEY, NULL,
+                       ieee802154_llsec_dump_devkeys),
+       IEEE802154_OP(IEEE802154_LLSEC_ADD_DEVKEY, ieee802154_llsec_add_devkey),
+       IEEE802154_OP(IEEE802154_LLSEC_DEL_DEVKEY, ieee802154_llsec_del_devkey),
 };
 
 static const struct genl_multicast_group ieee802154_mcgrps[] = {
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index fdd3d09..fa760d2 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -1174,7 +1174,7 @@ llsec_parse_dev(struct genl_info *info,
        dev->seclevel_exempt = 
!!nla_get_u8(info->attrs[IEEE802154_ATTR_LLSEC_DEV_OVERRIDE]);
        dev->key_mode = 
nla_get_u8(info->attrs[IEEE802154_ATTR_LLSEC_DEV_KEY_MODE]);
 
-       if (dev->key_mode > __IEEE802154_LLSEC_DEVKEY_MAX)
+       if (dev->key_mode >= __IEEE802154_LLSEC_DEVKEY_MAX)
                return -EINVAL;
 
        return 0;
@@ -1273,3 +1273,115 @@ int ieee802154_llsec_dump_devs(struct sk_buff *skb, 
struct netlink_callback *cb)
 {
        return ieee802154_llsec_dump_table(skb, cb, llsec_iter_devs);
 }
+
+
+
+static int llsec_add_devkey(struct net_device *dev, struct genl_info *info)
+{
+       struct ieee802154_mlme_ops *ops = ieee802154_mlme_ops(dev);
+       struct ieee802154_llsec_device_key key;
+       __le64 devaddr;
+
+       if (!info->attrs[IEEE802154_ATTR_LLSEC_FRAME_COUNTER] ||
+           !info->attrs[IEEE802154_ATTR_HW_ADDR] ||
+           ieee802154_llsec_parse_key_id(info, &key.key_id))
+               return -EINVAL;
+
+       devaddr = nla_get_hwaddr(info->attrs[IEEE802154_ATTR_HW_ADDR]);
+       key.frame_counter = 
nla_get_u32(info->attrs[IEEE802154_ATTR_LLSEC_FRAME_COUNTER]);
+
+       return ops->llsec->add_devkey(dev, devaddr, &key);
+}
+
+int ieee802154_llsec_add_devkey(struct sk_buff *skb, struct genl_info *info)
+{
+       return ieee802154_nl_llsec_change(skb, info, llsec_add_devkey);
+}
+
+static int llsec_del_devkey(struct net_device *dev, struct genl_info *info)
+{
+       struct ieee802154_mlme_ops *ops = ieee802154_mlme_ops(dev);
+       struct ieee802154_llsec_device_key key;
+       __le64 devaddr;
+
+       if (!info->attrs[IEEE802154_ATTR_HW_ADDR] ||
+           ieee802154_llsec_parse_key_id(info, &key.key_id))
+               return -EINVAL;
+
+       devaddr = nla_get_hwaddr(info->attrs[IEEE802154_ATTR_HW_ADDR]);
+
+       return ops->llsec->del_devkey(dev, devaddr, &key);
+}
+
+int ieee802154_llsec_del_devkey(struct sk_buff *skb, struct genl_info *info)
+{
+       return ieee802154_nl_llsec_change(skb, info, llsec_del_devkey);
+}
+
+static int
+ieee802154_nl_fill_devkey(struct sk_buff *msg, u32 portid, u32 seq,
+                         __le64 devaddr,
+                         const struct ieee802154_llsec_device_key *devkey,
+                         const struct net_device *dev)
+{
+       void *hdr;
+
+       hdr = genlmsg_put(msg, 0, seq, &nl802154_family, NLM_F_MULTI,
+                         IEEE802154_LLSEC_LIST_DEVKEY);
+       if (!hdr)
+               goto out;
+
+       if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) ||
+           nla_put_u32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex) ||
+           nla_put_hwaddr(msg, IEEE802154_ATTR_HW_ADDR, devaddr) ||
+           nla_put_u32(msg, IEEE802154_ATTR_LLSEC_FRAME_COUNTER,
+                       devkey->frame_counter) ||
+           ieee802154_llsec_fill_key_id(msg, &devkey->key_id))
+               goto nla_put_failure;
+
+       genlmsg_end(msg, hdr);
+       return 0;
+
+nla_put_failure:
+       genlmsg_cancel(msg, hdr);
+out:
+       return -EMSGSIZE;
+}
+
+static int llsec_iter_devkeys(struct llsec_dump_data *data)
+{
+       struct ieee802154_llsec_device *dpos;
+       struct ieee802154_llsec_device_key *kpos;
+       int rc = 0, idx = 0, idx2;
+
+       list_for_each_entry(dpos, &data->table->devices, list) {
+               if (idx++ < data->s_idx)
+                       continue;
+
+               idx2 = 0;
+
+               list_for_each_entry(kpos, &dpos->keys, list) {
+                       if (idx2++ < data->s_idx2)
+                               continue;
+
+                       if (ieee802154_nl_fill_devkey(data->skb, data->portid,
+                                                     data->nlmsg_seq,
+                                                     dpos->hwaddr, kpos,
+                                                     data->dev)) {
+                               return rc = -EMSGSIZE;
+                       }
+
+                       data->s_idx2++;
+               }
+
+               data->s_idx++;
+       }
+
+       return rc;
+}
+
+int ieee802154_llsec_dump_devkeys(struct sk_buff *skb,
+                                 struct netlink_callback *cb)
+{
+       return ieee802154_llsec_dump_table(skb, cb, llsec_iter_devkeys);
+}
-- 
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