aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAlexander Aring <alex.aring@gmail.com>2014-11-09 02:36:55 -0500
committerMarcel Holtmann <marcel@holtmann.org>2014-11-09 13:50:29 -0500
commit4b96aea0fcdbba18287f6cca87c8d796f33157b6 (patch)
tree24b66c550f99c6d20355e29dc29e2d0fbede8e5a /net
parentca20ce201c8d4123de0fd2b0d59ea19b0160d88f (diff)
ieee802154: add wpan_dev dump support
This patch adds support for wpan_dev dump via nl802154 framework. Signed-off-by: Alexander Aring <alex.aring@gmail.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r--net/ieee802154/nl802154.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
index 32e884732eb1..46df7dca92d9 100644
--- a/net/ieee802154/nl802154.c
+++ b/net/ieee802154/nl802154.c
@@ -198,6 +198,8 @@ static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = {
198 .len = 20-1 }, 198 .len = 20-1 },
199 199
200 [NL802154_ATTR_IFINDEX] = { .type = NLA_U32 }, 200 [NL802154_ATTR_IFINDEX] = { .type = NLA_U32 },
201 [NL802154_ATTR_IFTYPE] = { .type = NLA_U32 },
202 [NL802154_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
201 203
202 [NL802154_ATTR_WPAN_DEV] = { .type = NLA_U64 }, 204 [NL802154_ATTR_WPAN_DEV] = { .type = NLA_U64 },
203 205
@@ -209,6 +211,18 @@ static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = {
209 [NL802154_ATTR_CCA_MODE] = { .type = NLA_U8, }, 211 [NL802154_ATTR_CCA_MODE] = { .type = NLA_U8, },
210 212
211 [NL802154_ATTR_SUPPORTED_CHANNEL] = { .type = NLA_U32, }, 213 [NL802154_ATTR_SUPPORTED_CHANNEL] = { .type = NLA_U32, },
214
215 [NL802154_ATTR_PAN_ID] = { .type = NLA_U16, },
216 [NL802154_ATTR_EXTENDED_ADDR] = { .type = NLA_U64 },
217 [NL802154_ATTR_SHORT_ADDR] = { .type = NLA_U16, },
218
219 [NL802154_ATTR_MIN_BE] = { .type = NLA_U8, },
220 [NL802154_ATTR_MAX_BE] = { .type = NLA_U8, },
221 [NL802154_ATTR_MAX_CSMA_BACKOFFS] = { .type = NLA_U8, },
222
223 [NL802154_ATTR_MAX_FRAME_RETRIES] = { .type = NLA_S8, },
224
225 [NL802154_ATTR_LBT_MODE] = { .type = NLA_U8, },
212}; 226};
213 227
214/* message building helper */ 228/* message building helper */
@@ -414,6 +428,128 @@ static int nl802154_get_wpan_phy(struct sk_buff *skb, struct genl_info *info)
414 return genlmsg_reply(msg, info); 428 return genlmsg_reply(msg, info);
415} 429}
416 430
431static inline u64 wpan_dev_id(struct wpan_dev *wpan_dev)
432{
433 return (u64)wpan_dev->identifier |
434 ((u64)wpan_phy_to_rdev(wpan_dev->wpan_phy)->wpan_phy_idx << 32);
435}
436
437static int
438nl802154_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
439 struct cfg802154_registered_device *rdev,
440 struct wpan_dev *wpan_dev)
441{
442 struct net_device *dev = wpan_dev->netdev;
443 void *hdr;
444
445 hdr = nl802154hdr_put(msg, portid, seq, flags,
446 NL802154_CMD_NEW_INTERFACE);
447 if (!hdr)
448 return -1;
449
450 if (dev &&
451 (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex) ||
452 nla_put_string(msg, NL802154_ATTR_IFNAME, dev->name)))
453 goto nla_put_failure;
454
455 if (nla_put_u32(msg, NL802154_ATTR_WPAN_PHY, rdev->wpan_phy_idx) ||
456 nla_put_u32(msg, NL802154_ATTR_IFTYPE, wpan_dev->iftype) ||
457 nla_put_u64(msg, NL802154_ATTR_WPAN_DEV, wpan_dev_id(wpan_dev)) ||
458 nla_put_u32(msg, NL802154_ATTR_GENERATION,
459 rdev->devlist_generation ^
460 (cfg802154_rdev_list_generation << 2)))
461 goto nla_put_failure;
462
463 /* address settings */
464 if (nla_put_le64(msg, NL802154_ATTR_EXTENDED_ADDR,
465 wpan_dev->extended_addr) ||
466 nla_put_le16(msg, NL802154_ATTR_SHORT_ADDR,
467 wpan_dev->short_addr) ||
468 nla_put_le16(msg, NL802154_ATTR_PAN_ID, wpan_dev->pan_id))
469 goto nla_put_failure;
470
471 /* ARET handling */
472 if (nla_put_s8(msg, NL802154_ATTR_MAX_FRAME_RETRIES,
473 wpan_dev->frame_retries) ||
474 nla_put_u8(msg, NL802154_ATTR_MAX_BE, wpan_dev->max_be) ||
475 nla_put_u8(msg, NL802154_ATTR_MAX_CSMA_BACKOFFS,
476 wpan_dev->csma_retries) ||
477 nla_put_u8(msg, NL802154_ATTR_MIN_BE, wpan_dev->min_be))
478 goto nla_put_failure;
479
480 /* listen before transmit */
481 if (nla_put_u8(msg, NL802154_ATTR_LBT_MODE, wpan_dev->lbt))
482 goto nla_put_failure;
483
484 return genlmsg_end(msg, hdr);
485
486nla_put_failure:
487 genlmsg_cancel(msg, hdr);
488 return -EMSGSIZE;
489}
490
491static int
492nl802154_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
493{
494 int wp_idx = 0;
495 int if_idx = 0;
496 int wp_start = cb->args[0];
497 int if_start = cb->args[1];
498 struct cfg802154_registered_device *rdev;
499 struct wpan_dev *wpan_dev;
500
501 rtnl_lock();
502 list_for_each_entry(rdev, &cfg802154_rdev_list, list) {
503 /* TODO netns compare */
504 if (wp_idx < wp_start) {
505 wp_idx++;
506 continue;
507 }
508 if_idx = 0;
509
510 list_for_each_entry(wpan_dev, &rdev->wpan_dev_list, list) {
511 if (if_idx < if_start) {
512 if_idx++;
513 continue;
514 }
515 if (nl802154_send_iface(skb, NETLINK_CB(cb->skb).portid,
516 cb->nlh->nlmsg_seq, NLM_F_MULTI,
517 rdev, wpan_dev) < 0) {
518 goto out;
519 }
520 if_idx++;
521 }
522
523 wp_idx++;
524 }
525out:
526 rtnl_unlock();
527
528 cb->args[0] = wp_idx;
529 cb->args[1] = if_idx;
530
531 return skb->len;
532}
533
534static int nl802154_get_interface(struct sk_buff *skb, struct genl_info *info)
535{
536 struct sk_buff *msg;
537 struct cfg802154_registered_device *rdev = info->user_ptr[0];
538 struct wpan_dev *wdev = info->user_ptr[1];
539
540 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
541 if (!msg)
542 return -ENOMEM;
543
544 if (nl802154_send_iface(msg, info->snd_portid, info->snd_seq, 0,
545 rdev, wdev) < 0) {
546 nlmsg_free(msg);
547 return -ENOBUFS;
548 }
549
550 return genlmsg_reply(msg, info);
551}
552
417#define NL802154_FLAG_NEED_WPAN_PHY 0x01 553#define NL802154_FLAG_NEED_WPAN_PHY 0x01
418#define NL802154_FLAG_NEED_NETDEV 0x02 554#define NL802154_FLAG_NEED_NETDEV 0x02
419#define NL802154_FLAG_NEED_RTNL 0x04 555#define NL802154_FLAG_NEED_RTNL 0x04
@@ -515,6 +651,15 @@ static const struct genl_ops nl802154_ops[] = {
515 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY | 651 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
516 NL802154_FLAG_NEED_RTNL, 652 NL802154_FLAG_NEED_RTNL,
517 }, 653 },
654 {
655 .cmd = NL802154_CMD_GET_INTERFACE,
656 .doit = nl802154_get_interface,
657 .dumpit = nl802154_dump_interface,
658 .policy = nl802154_policy,
659 /* can be retrieved by unprivileged users */
660 .internal_flags = NL802154_FLAG_NEED_WPAN_DEV |
661 NL802154_FLAG_NEED_RTNL,
662 },
518}; 663};
519 664
520/* initialisation/exit functions */ 665/* initialisation/exit functions */