Signed-off-by: Phoebe Buckheister <phoebe.buckheis...@itwm.fraunhofer.de>
---
 include/linux/nl802154.h    |    5 ++
 net/ieee802154/ieee802154.h |    4 ++
 net/ieee802154/netlink.c    |    4 ++
 net/ieee802154/nl-mac.c     |  128 +++++++++++++++++++++++++++++++++++++++++++
 net/ieee802154/nl_policy.c  |    2 +
 net/mac802154/llsec.c       |    1 +
 6 files changed, 144 insertions(+)

diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h
index 521d136..a31e747 100644
--- a/include/linux/nl802154.h
+++ b/include/linux/nl802154.h
@@ -90,6 +90,8 @@ enum {
        IEEE802154_ATTR_LLSEC_KEY_BYTES,
        IEEE802154_ATTR_LLSEC_KEY_USAGE_FRAME_TYPES,
        IEEE802154_ATTR_LLSEC_KEY_USAGE_COMMANDS,
+       IEEE802154_ATTR_LLSEC_DEV_OVERRIDE,
+       IEEE802154_ATTR_LLSEC_DEV_KEY_MODE,
 
        __IEEE802154_ATTR_MAX,
 };
@@ -150,6 +152,9 @@ enum {
        IEEE802154_LLSEC_LIST_KEY,
        IEEE802154_LLSEC_ADD_KEY,
        IEEE802154_LLSEC_DEL_KEY,
+       IEEE802154_LLSEC_LIST_DEV,
+       IEEE802154_LLSEC_ADD_DEV,
+       IEEE802154_LLSEC_DEL_DEV,
 
        __IEEE802154_CMD_MAX,
 };
diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h
index 4a77d37..5f410ca 100644
--- a/net/ieee802154/ieee802154.h
+++ b/net/ieee802154/ieee802154.h
@@ -74,5 +74,9 @@ int ieee802154_llsec_add_key(struct sk_buff *skb, struct 
genl_info *info);
 int ieee802154_llsec_del_key(struct sk_buff *skb, struct genl_info *info);
 int ieee802154_llsec_dump_keys(struct sk_buff *skb,
                               struct netlink_callback *cb);
+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);
 
 #endif
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 47705c0..63cd851 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -130,6 +130,10 @@ static const struct genl_ops ieee8021154_ops[] = {
                        ieee802154_llsec_dump_keys),
        IEEE802154_OP(IEEE802154_LLSEC_ADD_KEY, ieee802154_llsec_add_key),
        IEEE802154_OP(IEEE802154_LLSEC_DEL_KEY, ieee802154_llsec_del_key),
+       IEEE802154_DUMP(IEEE802154_LLSEC_LIST_DEV, NULL,
+                       ieee802154_llsec_dump_devs),
+       IEEE802154_OP(IEEE802154_LLSEC_ADD_DEV, ieee802154_llsec_add_dev),
+       IEEE802154_OP(IEEE802154_LLSEC_DEL_DEV, ieee802154_llsec_del_dev),
 };
 
 static const struct genl_multicast_group ieee802154_mcgrps[] = {
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index 31e77b5..fdd3d09 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -1145,3 +1145,131 @@ int ieee802154_llsec_dump_keys(struct sk_buff *skb, 
struct netlink_callback *cb)
 {
        return ieee802154_llsec_dump_table(skb, cb, llsec_iter_keys);
 }
+
+
+
+static int
+llsec_parse_dev(struct genl_info *info,
+               struct ieee802154_llsec_device *dev)
+{
+       memset(dev, 0, sizeof(*dev));
+
+       if (!info->attrs[IEEE802154_ATTR_LLSEC_FRAME_COUNTER] ||
+           !info->attrs[IEEE802154_ATTR_HW_ADDR] ||
+           !info->attrs[IEEE802154_ATTR_LLSEC_DEV_OVERRIDE] ||
+           !info->attrs[IEEE802154_ATTR_LLSEC_DEV_KEY_MODE] ||
+           (!!info->attrs[IEEE802154_ATTR_PAN_ID] !=
+            !!info->attrs[IEEE802154_ATTR_SHORT_ADDR]))
+               return -EINVAL;
+
+       if (info->attrs[IEEE802154_ATTR_PAN_ID]) {
+               dev->pan_id = 
nla_get_shortaddr(info->attrs[IEEE802154_ATTR_PAN_ID]);
+               dev->short_addr = 
nla_get_shortaddr(info->attrs[IEEE802154_ATTR_SHORT_ADDR]);
+       } else {
+               dev->short_addr = cpu_to_le16(IEEE802154_ADDR_UNDEF);
+       }
+
+       dev->hwaddr = nla_get_hwaddr(info->attrs[IEEE802154_ATTR_HW_ADDR]);
+       dev->frame_counter = 
nla_get_u32(info->attrs[IEEE802154_ATTR_LLSEC_FRAME_COUNTER]);
+       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)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int llsec_add_dev(struct net_device *dev, struct genl_info *info)
+{
+       struct ieee802154_mlme_ops *ops = ieee802154_mlme_ops(dev);
+       struct ieee802154_llsec_device desc;
+
+       if (llsec_parse_dev(info, &desc))
+               return -EINVAL;
+
+       return ops->llsec->add_dev(dev, &desc);
+}
+
+int ieee802154_llsec_add_dev(struct sk_buff *skb, struct genl_info *info)
+{
+       return ieee802154_nl_llsec_change(skb, info, llsec_add_dev);
+}
+
+static int llsec_del_dev(struct net_device *dev, struct genl_info *info)
+{
+       struct ieee802154_mlme_ops *ops = ieee802154_mlme_ops(dev);
+       __le64 devaddr;
+
+       if (!info->attrs[IEEE802154_ATTR_HW_ADDR])
+               return -EINVAL;
+
+       devaddr = nla_get_hwaddr(info->attrs[IEEE802154_ATTR_HW_ADDR]);
+
+       return ops->llsec->del_dev(dev, devaddr);
+}
+
+int ieee802154_llsec_del_dev(struct sk_buff *skb, struct genl_info *info)
+{
+       return ieee802154_nl_llsec_change(skb, info, llsec_del_dev);
+}
+
+static int
+ieee802154_nl_fill_dev(struct sk_buff *msg, u32 portid, u32 seq,
+                      const struct ieee802154_llsec_device *desc,
+                      const struct net_device *dev)
+{
+       void *hdr;
+
+       hdr = genlmsg_put(msg, 0, seq, &nl802154_family, NLM_F_MULTI,
+                         IEEE802154_LLSEC_LIST_DEV);
+       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_shortaddr(msg, IEEE802154_ATTR_PAN_ID, desc->pan_id) ||
+           nla_put_shortaddr(msg, IEEE802154_ATTR_SHORT_ADDR,
+                             desc->short_addr) ||
+           nla_put_hwaddr(msg, IEEE802154_ATTR_HW_ADDR, desc->hwaddr) ||
+           nla_put_u32(msg, IEEE802154_ATTR_LLSEC_FRAME_COUNTER,
+                       desc->frame_counter) ||
+           nla_put_u8(msg, IEEE802154_ATTR_LLSEC_DEV_OVERRIDE,
+                      desc->seclevel_exempt) ||
+           nla_put_u8(msg, IEEE802154_ATTR_LLSEC_DEV_KEY_MODE, desc->key_mode))
+               goto nla_put_failure;
+
+       genlmsg_end(msg, hdr);
+       return 0;
+
+nla_put_failure:
+       genlmsg_cancel(msg, hdr);
+out:
+       return -EMSGSIZE;
+}
+
+static int llsec_iter_devs(struct llsec_dump_data *data)
+{
+       struct ieee802154_llsec_device *pos;
+       int rc = 0, idx = 0;
+
+       list_for_each_entry(pos, &data->table->devices, list) {
+               if (idx++ < data->s_idx)
+                       continue;
+
+               if (ieee802154_nl_fill_dev(data->skb, data->portid,
+                                          data->nlmsg_seq, pos, data->dev)) {
+                       rc = -EMSGSIZE;
+                       break;
+               }
+
+               data->s_idx++;
+       }
+
+       return rc;
+}
+
+int ieee802154_llsec_dump_devs(struct sk_buff *skb, struct netlink_callback 
*cb)
+{
+       return ieee802154_llsec_dump_table(skb, cb, llsec_iter_devs);
+}
diff --git a/net/ieee802154/nl_policy.c b/net/ieee802154/nl_policy.c
index 01a1ecd..4d8a478 100644
--- a/net/ieee802154/nl_policy.c
+++ b/net/ieee802154/nl_policy.c
@@ -73,5 +73,7 @@ const struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX 
+ 1] = {
        [IEEE802154_ATTR_LLSEC_KEY_BYTES] = { .len = 16, },
        [IEEE802154_ATTR_LLSEC_KEY_USAGE_FRAME_TYPES] = { .type = NLA_U8, },
        [IEEE802154_ATTR_LLSEC_KEY_USAGE_COMMANDS] = { .len = 258 / 8 },
+       [IEEE802154_ATTR_LLSEC_DEV_OVERRIDE] = { .type = NLA_U8, },
+       [IEEE802154_ATTR_LLSEC_DEV_KEY_MODE] = { .type = NLA_U8, },
 };
 
diff --git a/net/mac802154/llsec.c b/net/mac802154/llsec.c
index c4548dc..d487606 100644
--- a/net/mac802154/llsec.c
+++ b/net/mac802154/llsec.c
@@ -409,6 +409,7 @@ int mac802154_llsec_dev_add(struct mac802154_llsec *sec,
                INIT_HLIST_NODE(&entry->bucket_s);
 
        hash_add_rcu(sec->devices_hw, &entry->bucket_hw, hwkey);
+       list_add_tail_rcu(&entry->dev.list, &sec->table.devices);
 
        return 0;
 }
-- 
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