^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Alexander Aring <aar@pengutronix.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Based on: net/wireless/nl80211.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/rtnetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <net/cfg802154.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <net/genetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <net/mac802154.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <net/netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <net/nl802154.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "nl802154.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "rdev-ops.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /* the netlink family */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static struct genl_family nl802154_fam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* multicast groups */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) enum nl802154_multicast_groups {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) NL802154_MCGRP_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static const struct genl_multicast_group nl802154_mcgrps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) [NL802154_MCGRP_CONFIG] = { .name = "config", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* returns ERR_PTR values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static struct wpan_dev *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) __cfg802154_wpan_dev_from_attrs(struct net *netns, struct nlattr **attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct cfg802154_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct wpan_dev *result = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) bool have_ifidx = attrs[NL802154_ATTR_IFINDEX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) bool have_wpan_dev_id = attrs[NL802154_ATTR_WPAN_DEV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) u64 wpan_dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int wpan_phy_idx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) int ifidx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) ASSERT_RTNL();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (!have_ifidx && !have_wpan_dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (have_ifidx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) ifidx = nla_get_u32(attrs[NL802154_ATTR_IFINDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (have_wpan_dev_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) wpan_dev_id = nla_get_u64(attrs[NL802154_ATTR_WPAN_DEV]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) wpan_phy_idx = wpan_dev_id >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) list_for_each_entry(rdev, &cfg802154_rdev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct wpan_dev *wpan_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (wpan_phy_net(&rdev->wpan_phy) != netns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (have_wpan_dev_id && rdev->wpan_phy_idx != wpan_phy_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) list_for_each_entry(wpan_dev, &rdev->wpan_dev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (have_ifidx && wpan_dev->netdev &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) wpan_dev->netdev->ifindex == ifidx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) result = wpan_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (have_wpan_dev_id &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) wpan_dev->identifier == (u32)wpan_dev_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) result = wpan_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static struct cfg802154_registered_device *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) __cfg802154_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct cfg802154_registered_device *rdev = NULL, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct net_device *netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) ASSERT_RTNL();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (!attrs[NL802154_ATTR_WPAN_PHY] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) !attrs[NL802154_ATTR_IFINDEX] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) !attrs[NL802154_ATTR_WPAN_DEV])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (attrs[NL802154_ATTR_WPAN_PHY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) rdev = cfg802154_rdev_by_wpan_phy_idx(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) nla_get_u32(attrs[NL802154_ATTR_WPAN_PHY]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (attrs[NL802154_ATTR_WPAN_DEV]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) u64 wpan_dev_id = nla_get_u64(attrs[NL802154_ATTR_WPAN_DEV]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct wpan_dev *wpan_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) tmp = cfg802154_rdev_by_wpan_phy_idx(wpan_dev_id >> 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* make sure wpan_dev exists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) list_for_each_entry(wpan_dev, &tmp->wpan_dev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (wpan_dev->identifier != (u32)wpan_dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (!found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) tmp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (rdev && tmp != rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) rdev = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (attrs[NL802154_ATTR_IFINDEX]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int ifindex = nla_get_u32(attrs[NL802154_ATTR_IFINDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) netdev = __dev_get_by_index(netns, ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (netdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (netdev->ieee802154_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) tmp = wpan_phy_to_rdev(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) netdev->ieee802154_ptr->wpan_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) tmp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* not wireless device -- return error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (!tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /* mismatch -- return error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (rdev && tmp != rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) rdev = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (!rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (netns != wpan_phy_net(&rdev->wpan_phy))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* This function returns a pointer to the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * that the genl_info item that is passed refers to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * The result of this can be a PTR_ERR and hence must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * be checked with IS_ERR() for errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static struct cfg802154_registered_device *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) cfg802154_get_dev_from_info(struct net *netns, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return __cfg802154_rdev_from_attrs(netns, info->attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /* policy for the attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) [NL802154_ATTR_WPAN_PHY] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) [NL802154_ATTR_WPAN_PHY_NAME] = { .type = NLA_NUL_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) .len = 20-1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) [NL802154_ATTR_IFINDEX] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) [NL802154_ATTR_IFTYPE] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) [NL802154_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) [NL802154_ATTR_WPAN_DEV] = { .type = NLA_U64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) [NL802154_ATTR_PAGE] = { .type = NLA_U8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) [NL802154_ATTR_CHANNEL] = { .type = NLA_U8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) [NL802154_ATTR_TX_POWER] = { .type = NLA_S32, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) [NL802154_ATTR_CCA_MODE] = { .type = NLA_U32, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) [NL802154_ATTR_CCA_OPT] = { .type = NLA_U32, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) [NL802154_ATTR_CCA_ED_LEVEL] = { .type = NLA_S32, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) [NL802154_ATTR_SUPPORTED_CHANNEL] = { .type = NLA_U32, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) [NL802154_ATTR_PAN_ID] = { .type = NLA_U16, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) [NL802154_ATTR_EXTENDED_ADDR] = { .type = NLA_U64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) [NL802154_ATTR_SHORT_ADDR] = { .type = NLA_U16, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) [NL802154_ATTR_MIN_BE] = { .type = NLA_U8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) [NL802154_ATTR_MAX_BE] = { .type = NLA_U8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) [NL802154_ATTR_MAX_CSMA_BACKOFFS] = { .type = NLA_U8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) [NL802154_ATTR_MAX_FRAME_RETRIES] = { .type = NLA_S8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) [NL802154_ATTR_LBT_MODE] = { .type = NLA_U8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) [NL802154_ATTR_WPAN_PHY_CAPS] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) [NL802154_ATTR_SUPPORTED_COMMANDS] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) [NL802154_ATTR_ACKREQ_DEFAULT] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) [NL802154_ATTR_PID] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) [NL802154_ATTR_NETNS_FD] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) [NL802154_ATTR_SEC_ENABLED] = { .type = NLA_U8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) [NL802154_ATTR_SEC_OUT_LEVEL] = { .type = NLA_U32, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) [NL802154_ATTR_SEC_OUT_KEY_ID] = { .type = NLA_NESTED, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) [NL802154_ATTR_SEC_FRAME_COUNTER] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) [NL802154_ATTR_SEC_LEVEL] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) [NL802154_ATTR_SEC_DEVICE] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) [NL802154_ATTR_SEC_DEVKEY] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) [NL802154_ATTR_SEC_KEY] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) nl802154_prepare_wpan_dev_dump(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct cfg802154_registered_device **rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct wpan_dev **wpan_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) const struct genl_dumpit_info *info = genl_dumpit_info(cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (!cb->args[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) *wpan_dev = __cfg802154_wpan_dev_from_attrs(sock_net(skb->sk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) info->attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (IS_ERR(*wpan_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) err = PTR_ERR(*wpan_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) *rdev = wpan_phy_to_rdev((*wpan_dev)->wpan_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* 0 is the first index - add 1 to parse only once */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) cb->args[0] = (*rdev)->wpan_phy_idx + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) cb->args[1] = (*wpan_dev)->identifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* subtract the 1 again here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct wpan_phy *wpan_phy = wpan_phy_idx_to_wpan_phy(cb->args[0] - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct wpan_dev *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (!wpan_phy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) *rdev = wpan_phy_to_rdev(wpan_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) *wpan_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) list_for_each_entry(tmp, &(*rdev)->wpan_dev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (tmp->identifier == cb->args[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) *wpan_dev = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (!*wpan_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) nl802154_finish_wpan_dev_dump(struct cfg802154_registered_device *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /* message building helper */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static inline void *nl802154hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) int flags, u8 cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) /* since there is no private header just add the generic one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return genlmsg_put(skb, portid, seq, &nl802154_fam, flags, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) nl802154_put_flags(struct sk_buff *msg, int attr, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct nlattr *nl_flags = nla_nest_start_noflag(msg, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (!nl_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) while (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if ((mask & 1) && nla_put_flag(msg, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) mask >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) nla_nest_end(msg, nl_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) nl802154_send_wpan_phy_channels(struct cfg802154_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct sk_buff *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct nlattr *nl_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) unsigned long page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) nl_page = nla_nest_start_noflag(msg, NL802154_ATTR_CHANNELS_SUPPORTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (!nl_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) for (page = 0; page <= IEEE802154_MAX_PAGE; page++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (nla_put_u32(msg, NL802154_ATTR_SUPPORTED_CHANNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) rdev->wpan_phy.supported.channels[page]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) nla_nest_end(msg, nl_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) nl802154_put_capabilities(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct cfg802154_registered_device *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) const struct wpan_phy_supported *caps = &rdev->wpan_phy.supported;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct nlattr *nl_caps, *nl_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) nl_caps = nla_nest_start_noflag(msg, NL802154_ATTR_WPAN_PHY_CAPS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (!nl_caps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) nl_channels = nla_nest_start_noflag(msg, NL802154_CAP_ATTR_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (!nl_channels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) for (i = 0; i <= IEEE802154_MAX_PAGE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (caps->channels[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (nl802154_put_flags(msg, i, caps->channels[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) nla_nest_end(msg, nl_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_ED_LEVEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) struct nlattr *nl_ed_lvls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) nl_ed_lvls = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) NL802154_CAP_ATTR_CCA_ED_LEVELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (!nl_ed_lvls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) for (i = 0; i < caps->cca_ed_levels_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (nla_put_s32(msg, i, caps->cca_ed_levels[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) nla_nest_end(msg, nl_ed_lvls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_TXPOWER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct nlattr *nl_tx_pwrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) nl_tx_pwrs = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) NL802154_CAP_ATTR_TX_POWERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (!nl_tx_pwrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) for (i = 0; i < caps->tx_powers_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (nla_put_s32(msg, i, caps->tx_powers[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) nla_nest_end(msg, nl_tx_pwrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (nl802154_put_flags(msg, NL802154_CAP_ATTR_CCA_MODES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) caps->cca_modes) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) nl802154_put_flags(msg, NL802154_CAP_ATTR_CCA_OPTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) caps->cca_opts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (nla_put_u8(msg, NL802154_CAP_ATTR_MIN_MINBE, caps->min_minbe) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) nla_put_u8(msg, NL802154_CAP_ATTR_MAX_MINBE, caps->max_minbe) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) nla_put_u8(msg, NL802154_CAP_ATTR_MIN_MAXBE, caps->min_maxbe) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) nla_put_u8(msg, NL802154_CAP_ATTR_MAX_MAXBE, caps->max_maxbe) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) nla_put_u8(msg, NL802154_CAP_ATTR_MIN_CSMA_BACKOFFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) caps->min_csma_backoffs) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) nla_put_u8(msg, NL802154_CAP_ATTR_MAX_CSMA_BACKOFFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) caps->max_csma_backoffs) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) nla_put_s8(msg, NL802154_CAP_ATTR_MIN_FRAME_RETRIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) caps->min_frame_retries) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) nla_put_s8(msg, NL802154_CAP_ATTR_MAX_FRAME_RETRIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) caps->max_frame_retries) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) nl802154_put_flags(msg, NL802154_CAP_ATTR_IFTYPES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) caps->iftypes) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) nla_put_u32(msg, NL802154_CAP_ATTR_LBT, caps->lbt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) nla_nest_end(msg, nl_caps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) static int nl802154_send_wpan_phy(struct cfg802154_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) enum nl802154_commands cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct sk_buff *msg, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct nlattr *nl_cmds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (nla_put_u32(msg, NL802154_ATTR_WPAN_PHY, rdev->wpan_phy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) nla_put_string(msg, NL802154_ATTR_WPAN_PHY_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) wpan_phy_name(&rdev->wpan_phy)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) nla_put_u32(msg, NL802154_ATTR_GENERATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) cfg802154_rdev_list_generation))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (cmd != NL802154_CMD_NEW_WPAN_PHY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) goto finish;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /* DUMP PHY PIB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /* current channel settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (nla_put_u8(msg, NL802154_ATTR_PAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) rdev->wpan_phy.current_page) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) nla_put_u8(msg, NL802154_ATTR_CHANNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) rdev->wpan_phy.current_channel))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /* TODO remove this behaviour, we still keep support it for a while
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * so users can change the behaviour to the new one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (nl802154_send_wpan_phy_channels(rdev, msg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) /* cca mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (nla_put_u32(msg, NL802154_ATTR_CCA_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) rdev->wpan_phy.cca.mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (rdev->wpan_phy.cca.mode == NL802154_CCA_ENERGY_CARRIER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (nla_put_u32(msg, NL802154_ATTR_CCA_OPT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) rdev->wpan_phy.cca.opt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_TXPOWER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (nla_put_s32(msg, NL802154_ATTR_TX_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) rdev->wpan_phy.transmit_power))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_ED_LEVEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (nla_put_s32(msg, NL802154_ATTR_CCA_ED_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) rdev->wpan_phy.cca_ed_level))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (nl802154_put_capabilities(msg, rdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) nl_cmds = nla_nest_start_noflag(msg, NL802154_ATTR_SUPPORTED_COMMANDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (!nl_cmds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) #define CMD(op, n) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (rdev->ops->op) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) i++; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (nla_put_u32(msg, i, NL802154_CMD_ ## n)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) goto nla_put_failure; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) CMD(add_virtual_intf, NEW_INTERFACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) CMD(del_virtual_intf, DEL_INTERFACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) CMD(set_channel, SET_CHANNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) CMD(set_pan_id, SET_PAN_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) CMD(set_short_addr, SET_SHORT_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) CMD(set_backoff_exponent, SET_BACKOFF_EXPONENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) CMD(set_max_csma_backoffs, SET_MAX_CSMA_BACKOFFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) CMD(set_max_frame_retries, SET_MAX_FRAME_RETRIES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) CMD(set_lbt_mode, SET_LBT_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) CMD(set_ackreq_default, SET_ACKREQ_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_TXPOWER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) CMD(set_tx_power, SET_TX_POWER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_ED_LEVEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) CMD(set_cca_ed_level, SET_CCA_ED_LEVEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) CMD(set_cca_mode, SET_CCA_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) #undef CMD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) nla_nest_end(msg, nl_cmds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) struct nl802154_dump_wpan_phy_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) s64 filter_wpan_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) long start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) static int nl802154_dump_wpan_phy_parse(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct nl802154_dump_wpan_phy_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) const struct genl_dumpit_info *info = genl_dumpit_info(cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) struct nlattr **tb = info->attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (tb[NL802154_ATTR_WPAN_PHY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) state->filter_wpan_phy = nla_get_u32(tb[NL802154_ATTR_WPAN_PHY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (tb[NL802154_ATTR_WPAN_DEV])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) state->filter_wpan_phy = nla_get_u64(tb[NL802154_ATTR_WPAN_DEV]) >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (tb[NL802154_ATTR_IFINDEX]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) struct net_device *netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) struct cfg802154_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) int ifidx = nla_get_u32(tb[NL802154_ATTR_IFINDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) netdev = __dev_get_by_index(&init_net, ifidx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (!netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (netdev->ieee802154_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) rdev = wpan_phy_to_rdev(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) netdev->ieee802154_ptr->wpan_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) state->filter_wpan_phy = rdev->wpan_phy_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) nl802154_dump_wpan_phy(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) int idx = 0, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) struct nl802154_dump_wpan_phy_state *state = (void *)cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct cfg802154_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (!state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) state = kzalloc(sizeof(*state), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (!state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) state->filter_wpan_phy = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) ret = nl802154_dump_wpan_phy_parse(skb, cb, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) kfree(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) cb->args[0] = (long)state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) list_for_each_entry(rdev, &cfg802154_rdev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (!net_eq(wpan_phy_net(&rdev->wpan_phy), sock_net(skb->sk)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (++idx <= state->start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (state->filter_wpan_phy != -1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) state->filter_wpan_phy != rdev->wpan_phy_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) /* attempt to fit multiple wpan_phy data chunks into the skb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) ret = nl802154_send_wpan_phy(rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) NL802154_CMD_NEW_WPAN_PHY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) cb->nlh->nlmsg_seq, NLM_F_MULTI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) !skb->len && cb->min_dump_alloc < 4096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) cb->min_dump_alloc = 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) idx--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) state->start = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static int nl802154_dump_wpan_phy_done(struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) kfree((void *)cb->args[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) static int nl802154_get_wpan_phy(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (nl802154_send_wpan_phy(rdev, NL802154_CMD_NEW_WPAN_PHY, msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) info->snd_portid, info->snd_seq, 0) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) static inline u64 wpan_dev_id(struct wpan_dev *wpan_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) return (u64)wpan_dev->identifier |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) ((u64)wpan_phy_to_rdev(wpan_dev->wpan_phy)->wpan_phy_idx << 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) #include <net/ieee802154_netdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) ieee802154_llsec_send_key_id(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) const struct ieee802154_llsec_key_id *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct nlattr *nl_dev_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (nla_put_u32(msg, NL802154_KEY_ID_ATTR_MODE, desc->mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) switch (desc->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) case NL802154_KEY_ID_MODE_IMPLICIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) nl_dev_addr = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) NL802154_KEY_ID_ATTR_IMPLICIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (!nl_dev_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (nla_put_le16(msg, NL802154_DEV_ADDR_ATTR_PAN_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) desc->device_addr.pan_id) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) nla_put_u32(msg, NL802154_DEV_ADDR_ATTR_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) desc->device_addr.mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) switch (desc->device_addr.mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) case NL802154_DEV_ADDR_SHORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (nla_put_le16(msg, NL802154_DEV_ADDR_ATTR_SHORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) desc->device_addr.short_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) case NL802154_DEV_ADDR_EXTENDED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (nla_put_le64(msg, NL802154_DEV_ADDR_ATTR_EXTENDED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) desc->device_addr.extended_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) NL802154_DEV_ADDR_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) /* userspace should handle unknown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) nla_nest_end(msg, nl_dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) case NL802154_KEY_ID_MODE_INDEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) case NL802154_KEY_ID_MODE_INDEX_SHORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) /* TODO renmae short_source? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (nla_put_le32(msg, NL802154_KEY_ID_ATTR_SOURCE_SHORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) desc->short_source))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) case NL802154_KEY_ID_MODE_INDEX_EXTENDED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (nla_put_le64(msg, NL802154_KEY_ID_ATTR_SOURCE_EXTENDED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) desc->extended_source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) NL802154_KEY_ID_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) /* userspace should handle unknown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) /* TODO key_id to key_idx ? Check naming */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (desc->mode != NL802154_KEY_ID_MODE_IMPLICIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (nla_put_u8(msg, NL802154_KEY_ID_ATTR_INDEX, desc->id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) static int nl802154_get_llsec_params(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct cfg802154_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) struct wpan_dev *wpan_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) struct nlattr *nl_key_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) struct ieee802154_llsec_params params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) ret = rdev_get_llsec_params(rdev, wpan_dev, ¶ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (nla_put_u8(msg, NL802154_ATTR_SEC_ENABLED, params.enabled) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) nla_put_u32(msg, NL802154_ATTR_SEC_OUT_LEVEL, params.out_level) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) nla_put_be32(msg, NL802154_ATTR_SEC_FRAME_COUNTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) params.frame_counter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) nl_key_id = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_OUT_KEY_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (!nl_key_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) ret = ieee802154_llsec_send_key_id(msg, ¶ms.out_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) nla_nest_end(msg, nl_key_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) nl802154_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) struct cfg802154_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct wpan_dev *wpan_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) struct net_device *dev = wpan_dev->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) hdr = nl802154hdr_put(msg, portid, seq, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) NL802154_CMD_NEW_INTERFACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (dev &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) nla_put_string(msg, NL802154_ATTR_IFNAME, dev->name)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (nla_put_u32(msg, NL802154_ATTR_WPAN_PHY, rdev->wpan_phy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) nla_put_u32(msg, NL802154_ATTR_IFTYPE, wpan_dev->iftype) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) nla_put_u64_64bit(msg, NL802154_ATTR_WPAN_DEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) wpan_dev_id(wpan_dev), NL802154_ATTR_PAD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) nla_put_u32(msg, NL802154_ATTR_GENERATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) rdev->devlist_generation ^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) (cfg802154_rdev_list_generation << 2)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) /* address settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if (nla_put_le64(msg, NL802154_ATTR_EXTENDED_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) wpan_dev->extended_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) NL802154_ATTR_PAD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) nla_put_le16(msg, NL802154_ATTR_SHORT_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) wpan_dev->short_addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) nla_put_le16(msg, NL802154_ATTR_PAN_ID, wpan_dev->pan_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) /* ARET handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (nla_put_s8(msg, NL802154_ATTR_MAX_FRAME_RETRIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) wpan_dev->frame_retries) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) nla_put_u8(msg, NL802154_ATTR_MAX_BE, wpan_dev->max_be) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) nla_put_u8(msg, NL802154_ATTR_MAX_CSMA_BACKOFFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) wpan_dev->csma_retries) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) nla_put_u8(msg, NL802154_ATTR_MIN_BE, wpan_dev->min_be))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /* listen before transmit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (nla_put_u8(msg, NL802154_ATTR_LBT_MODE, wpan_dev->lbt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) /* ackreq default behaviour */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (nla_put_u8(msg, NL802154_ATTR_ACKREQ_DEFAULT, wpan_dev->ackreq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (nl802154_get_llsec_params(msg, rdev, wpan_dev) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) nl802154_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) int wp_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) int if_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) int wp_start = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) int if_start = cb->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) struct cfg802154_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) struct wpan_dev *wpan_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) list_for_each_entry(rdev, &cfg802154_rdev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if (!net_eq(wpan_phy_net(&rdev->wpan_phy), sock_net(skb->sk)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (wp_idx < wp_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) wp_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) list_for_each_entry(wpan_dev, &rdev->wpan_dev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (if_idx < if_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) if_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (nl802154_send_iface(skb, NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) cb->nlh->nlmsg_seq, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) rdev, wpan_dev) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) wp_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) cb->args[0] = wp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) cb->args[1] = if_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) static int nl802154_get_interface(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) struct wpan_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if (nl802154_send_iface(msg, info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) rdev, wdev) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) static int nl802154_new_interface(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) enum nl802154_iftype type = NL802154_IFTYPE_UNSPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) __le64 extended_addr = cpu_to_le64(0x0000000000000000ULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) /* TODO avoid failing a new interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) * creation due to pending removal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (!info->attrs[NL802154_ATTR_IFNAME])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (info->attrs[NL802154_ATTR_IFTYPE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) type = nla_get_u32(info->attrs[NL802154_ATTR_IFTYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if (type > NL802154_IFTYPE_MAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) !(rdev->wpan_phy.supported.iftypes & BIT(type)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (info->attrs[NL802154_ATTR_EXTENDED_ADDR])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) extended_addr = nla_get_le64(info->attrs[NL802154_ATTR_EXTENDED_ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (!rdev->ops->add_virtual_intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) return rdev_add_virtual_intf(rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) nla_data(info->attrs[NL802154_ATTR_IFNAME]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) NET_NAME_USER, type, extended_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) static int nl802154_del_interface(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) struct wpan_dev *wpan_dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (!rdev->ops->del_virtual_intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) /* If we remove a wpan device without a netdev then clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) * user_ptr[1] so that nl802154_post_doit won't dereference it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) * to check if it needs to do dev_put(). Otherwise it crashes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) * since the wpan_dev has been freed, unlike with a netdev where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) * we need the dev_put() for the netdev to really be freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (!wpan_dev->netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) info->user_ptr[1] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) return rdev_del_virtual_intf(rdev, wpan_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) u8 channel, page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (!info->attrs[NL802154_ATTR_PAGE] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) !info->attrs[NL802154_ATTR_CHANNEL])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) page = nla_get_u8(info->attrs[NL802154_ATTR_PAGE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) channel = nla_get_u8(info->attrs[NL802154_ATTR_CHANNEL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) /* check 802.15.4 constraints */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (page > IEEE802154_MAX_PAGE || channel > IEEE802154_MAX_CHANNEL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) !(rdev->wpan_phy.supported.channels[page] & BIT(channel)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) return rdev_set_channel(rdev, page, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) static int nl802154_set_cca_mode(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) struct wpan_phy_cca cca;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (!(rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_MODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (!info->attrs[NL802154_ATTR_CCA_MODE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) cca.mode = nla_get_u32(info->attrs[NL802154_ATTR_CCA_MODE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) /* checking 802.15.4 constraints */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (cca.mode < NL802154_CCA_ENERGY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) cca.mode > NL802154_CCA_ATTR_MAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) !(rdev->wpan_phy.supported.cca_modes & BIT(cca.mode)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (cca.mode == NL802154_CCA_ENERGY_CARRIER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) if (!info->attrs[NL802154_ATTR_CCA_OPT])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) cca.opt = nla_get_u32(info->attrs[NL802154_ATTR_CCA_OPT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) if (cca.opt > NL802154_CCA_OPT_ATTR_MAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) !(rdev->wpan_phy.supported.cca_opts & BIT(cca.opt)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) return rdev_set_cca_mode(rdev, &cca);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) static int nl802154_set_cca_ed_level(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) s32 ed_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (!(rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_ED_LEVEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (!info->attrs[NL802154_ATTR_CCA_ED_LEVEL])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) ed_level = nla_get_s32(info->attrs[NL802154_ATTR_CCA_ED_LEVEL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) for (i = 0; i < rdev->wpan_phy.supported.cca_ed_levels_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) if (ed_level == rdev->wpan_phy.supported.cca_ed_levels[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) return rdev_set_cca_ed_level(rdev, ed_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) static int nl802154_set_tx_power(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) s32 power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) if (!(rdev->wpan_phy.flags & WPAN_PHY_FLAG_TXPOWER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (!info->attrs[NL802154_ATTR_TX_POWER])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) power = nla_get_s32(info->attrs[NL802154_ATTR_TX_POWER]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) for (i = 0; i < rdev->wpan_phy.supported.tx_powers_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (power == rdev->wpan_phy.supported.tx_powers[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) return rdev_set_tx_power(rdev, power);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) static int nl802154_set_pan_id(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) __le16 pan_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) /* conflict here while tx/rx calls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (wpan_dev->lowpan_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if (netif_running(wpan_dev->lowpan_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) /* don't change address fields on monitor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) !info->attrs[NL802154_ATTR_PAN_ID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) pan_id = nla_get_le16(info->attrs[NL802154_ATTR_PAN_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) /* TODO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) * I am not sure about to check here on broadcast pan_id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) * Broadcast is a valid setting, comment from 802.15.4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) * If this value is 0xffff, the device is not associated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) * This could useful to simple deassociate an device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) if (pan_id == cpu_to_le16(IEEE802154_PAN_ID_BROADCAST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) return rdev_set_pan_id(rdev, wpan_dev, pan_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) static int nl802154_set_short_addr(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) __le16 short_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) /* conflict here while tx/rx calls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) if (netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (wpan_dev->lowpan_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if (netif_running(wpan_dev->lowpan_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) /* don't change address fields on monitor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) !info->attrs[NL802154_ATTR_SHORT_ADDR])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) short_addr = nla_get_le16(info->attrs[NL802154_ATTR_SHORT_ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) /* TODO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) * I am not sure about to check here on broadcast short_addr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) * Broadcast is a valid setting, comment from 802.15.4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) * A value of 0xfffe indicates that the device has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) * associated but has not been allocated an address. A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) * value of 0xffff indicates that the device does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) * have a short address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) * I think we should allow to set these settings but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) * don't allow to allow socket communication with it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (short_addr == cpu_to_le16(IEEE802154_ADDR_SHORT_UNSPEC) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) short_addr == cpu_to_le16(IEEE802154_ADDR_SHORT_BROADCAST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) return rdev_set_short_addr(rdev, wpan_dev, short_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) nl802154_set_backoff_exponent(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) u8 min_be, max_be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) /* should be set on netif open inside phy settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) if (netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (!info->attrs[NL802154_ATTR_MIN_BE] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) !info->attrs[NL802154_ATTR_MAX_BE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) min_be = nla_get_u8(info->attrs[NL802154_ATTR_MIN_BE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) max_be = nla_get_u8(info->attrs[NL802154_ATTR_MAX_BE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) /* check 802.15.4 constraints */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) if (min_be < rdev->wpan_phy.supported.min_minbe ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) min_be > rdev->wpan_phy.supported.max_minbe ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) max_be < rdev->wpan_phy.supported.min_maxbe ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) max_be > rdev->wpan_phy.supported.max_maxbe ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) min_be > max_be)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) return rdev_set_backoff_exponent(rdev, wpan_dev, min_be, max_be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) nl802154_set_max_csma_backoffs(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) u8 max_csma_backoffs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) /* conflict here while other running iface settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) if (netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (!info->attrs[NL802154_ATTR_MAX_CSMA_BACKOFFS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) max_csma_backoffs = nla_get_u8(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) info->attrs[NL802154_ATTR_MAX_CSMA_BACKOFFS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) /* check 802.15.4 constraints */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (max_csma_backoffs < rdev->wpan_phy.supported.min_csma_backoffs ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) max_csma_backoffs > rdev->wpan_phy.supported.max_csma_backoffs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) return rdev_set_max_csma_backoffs(rdev, wpan_dev, max_csma_backoffs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) nl802154_set_max_frame_retries(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) s8 max_frame_retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) if (netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) if (!info->attrs[NL802154_ATTR_MAX_FRAME_RETRIES])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) max_frame_retries = nla_get_s8(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) info->attrs[NL802154_ATTR_MAX_FRAME_RETRIES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) /* check 802.15.4 constraints */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if (max_frame_retries < rdev->wpan_phy.supported.min_frame_retries ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) max_frame_retries > rdev->wpan_phy.supported.max_frame_retries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) return rdev_set_max_frame_retries(rdev, wpan_dev, max_frame_retries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) static int nl802154_set_lbt_mode(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) int mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) if (netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) if (!info->attrs[NL802154_ATTR_LBT_MODE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) mode = nla_get_u8(info->attrs[NL802154_ATTR_LBT_MODE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) if (mode != 0 && mode != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) if (!wpan_phy_supported_bool(mode, rdev->wpan_phy.supported.lbt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) return rdev_set_lbt_mode(rdev, wpan_dev, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) nl802154_set_ackreq_default(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) int ackreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) if (!info->attrs[NL802154_ATTR_ACKREQ_DEFAULT])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) ackreq = nla_get_u8(info->attrs[NL802154_ATTR_ACKREQ_DEFAULT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) if (ackreq != 0 && ackreq != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) return rdev_set_ackreq_default(rdev, wpan_dev, ackreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) static int nl802154_wpan_phy_netns(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) struct net *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) if (info->attrs[NL802154_ATTR_PID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) u32 pid = nla_get_u32(info->attrs[NL802154_ATTR_PID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) net = get_net_ns_by_pid(pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) } else if (info->attrs[NL802154_ATTR_NETNS_FD]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) u32 fd = nla_get_u32(info->attrs[NL802154_ATTR_NETNS_FD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) net = get_net_ns_by_fd(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) if (IS_ERR(net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) return PTR_ERR(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) /* check if anything to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) if (!net_eq(wpan_phy_net(&rdev->wpan_phy), net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) err = cfg802154_switch_netns(rdev, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) put_net(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) static const struct nla_policy nl802154_dev_addr_policy[NL802154_DEV_ADDR_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) [NL802154_DEV_ADDR_ATTR_PAN_ID] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) [NL802154_DEV_ADDR_ATTR_MODE] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) [NL802154_DEV_ADDR_ATTR_SHORT] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) [NL802154_DEV_ADDR_ATTR_EXTENDED] = { .type = NLA_U64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) ieee802154_llsec_parse_dev_addr(struct nlattr *nla,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) struct ieee802154_addr *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) struct nlattr *attrs[NL802154_DEV_ADDR_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) if (!nla || nla_parse_nested_deprecated(attrs, NL802154_DEV_ADDR_ATTR_MAX, nla, nl802154_dev_addr_policy, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (!attrs[NL802154_DEV_ADDR_ATTR_PAN_ID] || !attrs[NL802154_DEV_ADDR_ATTR_MODE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) addr->pan_id = nla_get_le16(attrs[NL802154_DEV_ADDR_ATTR_PAN_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) addr->mode = nla_get_u32(attrs[NL802154_DEV_ADDR_ATTR_MODE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) switch (addr->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) case NL802154_DEV_ADDR_SHORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) if (!attrs[NL802154_DEV_ADDR_ATTR_SHORT])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) addr->short_addr = nla_get_le16(attrs[NL802154_DEV_ADDR_ATTR_SHORT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) case NL802154_DEV_ADDR_EXTENDED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) if (!attrs[NL802154_DEV_ADDR_ATTR_EXTENDED])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) addr->extended_addr = nla_get_le64(attrs[NL802154_DEV_ADDR_ATTR_EXTENDED]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) static const struct nla_policy nl802154_key_id_policy[NL802154_KEY_ID_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) [NL802154_KEY_ID_ATTR_MODE] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) [NL802154_KEY_ID_ATTR_INDEX] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) [NL802154_KEY_ID_ATTR_IMPLICIT] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) [NL802154_KEY_ID_ATTR_SOURCE_SHORT] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) [NL802154_KEY_ID_ATTR_SOURCE_EXTENDED] = { .type = NLA_U64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) ieee802154_llsec_parse_key_id(struct nlattr *nla,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) struct ieee802154_llsec_key_id *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) struct nlattr *attrs[NL802154_KEY_ID_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (!nla || nla_parse_nested_deprecated(attrs, NL802154_KEY_ID_ATTR_MAX, nla, nl802154_key_id_policy, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) if (!attrs[NL802154_KEY_ID_ATTR_MODE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) desc->mode = nla_get_u32(attrs[NL802154_KEY_ID_ATTR_MODE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) switch (desc->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) case NL802154_KEY_ID_MODE_IMPLICIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) if (!attrs[NL802154_KEY_ID_ATTR_IMPLICIT])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) if (ieee802154_llsec_parse_dev_addr(attrs[NL802154_KEY_ID_ATTR_IMPLICIT],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) &desc->device_addr) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) case NL802154_KEY_ID_MODE_INDEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) case NL802154_KEY_ID_MODE_INDEX_SHORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) if (!attrs[NL802154_KEY_ID_ATTR_SOURCE_SHORT])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) desc->short_source = nla_get_le32(attrs[NL802154_KEY_ID_ATTR_SOURCE_SHORT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) case NL802154_KEY_ID_MODE_INDEX_EXTENDED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) if (!attrs[NL802154_KEY_ID_ATTR_SOURCE_EXTENDED])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) desc->extended_source = nla_get_le64(attrs[NL802154_KEY_ID_ATTR_SOURCE_EXTENDED]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) if (desc->mode != NL802154_KEY_ID_MODE_IMPLICIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) if (!attrs[NL802154_KEY_ID_ATTR_INDEX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) /* TODO change id to idx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) desc->id = nla_get_u8(attrs[NL802154_KEY_ID_ATTR_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) static int nl802154_set_llsec_params(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) struct ieee802154_llsec_params params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) u32 changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) if (info->attrs[NL802154_ATTR_SEC_ENABLED]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) u8 enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) enabled = nla_get_u8(info->attrs[NL802154_ATTR_SEC_ENABLED]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) if (enabled != 0 && enabled != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) params.enabled = nla_get_u8(info->attrs[NL802154_ATTR_SEC_ENABLED]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) changed |= IEEE802154_LLSEC_PARAM_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) if (info->attrs[NL802154_ATTR_SEC_OUT_KEY_ID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) ret = ieee802154_llsec_parse_key_id(info->attrs[NL802154_ATTR_SEC_OUT_KEY_ID],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) ¶ms.out_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) changed |= IEEE802154_LLSEC_PARAM_OUT_KEY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) if (info->attrs[NL802154_ATTR_SEC_OUT_LEVEL]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) params.out_level = nla_get_u32(info->attrs[NL802154_ATTR_SEC_OUT_LEVEL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) if (params.out_level > NL802154_SECLEVEL_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) changed |= IEEE802154_LLSEC_PARAM_OUT_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) if (info->attrs[NL802154_ATTR_SEC_FRAME_COUNTER]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) params.frame_counter = nla_get_be32(info->attrs[NL802154_ATTR_SEC_FRAME_COUNTER]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) changed |= IEEE802154_LLSEC_PARAM_FRAME_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) return rdev_set_llsec_params(rdev, wpan_dev, ¶ms, changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) static int nl802154_send_key(struct sk_buff *msg, u32 cmd, u32 portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) u32 seq, int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) struct cfg802154_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) const struct ieee802154_llsec_key_entry *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) u32 commands[NL802154_CMD_FRAME_NR_IDS / 32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) struct nlattr *nl_key, *nl_key_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) nl_key = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) if (!nl_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) nl_key_id = nla_nest_start_noflag(msg, NL802154_KEY_ATTR_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) if (!nl_key_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) if (ieee802154_llsec_send_key_id(msg, &key->id) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) nla_nest_end(msg, nl_key_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) if (nla_put_u8(msg, NL802154_KEY_ATTR_USAGE_FRAMES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) key->key->frame_types))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) if (key->key->frame_types & BIT(NL802154_FRAME_CMD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) /* TODO for each nested */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) memset(commands, 0, sizeof(commands));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) commands[7] = key->key->cmd_frame_ids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) if (nla_put(msg, NL802154_KEY_ATTR_USAGE_CMDS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) sizeof(commands), commands))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) if (nla_put(msg, NL802154_KEY_ATTR_BYTES, NL802154_KEY_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) key->key->key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) nla_nest_end(msg, nl_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) nl802154_dump_llsec_key(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) struct cfg802154_registered_device *rdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) struct ieee802154_llsec_key_entry *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) struct ieee802154_llsec_table *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) struct wpan_dev *wpan_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) err = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) if (!wpan_dev->netdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) rdev_lock_llsec_table(rdev, wpan_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) rdev_get_llsec_table(rdev, wpan_dev, &table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) /* TODO make it like station dump */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) if (cb->args[2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) list_for_each_entry(key, &table->keys, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (nl802154_send_key(skb, NL802154_CMD_NEW_SEC_KEY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) cb->nlh->nlmsg_seq, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) rdev, wpan_dev->netdev, key) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) /* TODO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) rdev_unlock_llsec_table(rdev, wpan_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) cb->args[2] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) rdev_unlock_llsec_table(rdev, wpan_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) err = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) nl802154_finish_wpan_dev_dump(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) static const struct nla_policy nl802154_key_policy[NL802154_KEY_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) [NL802154_KEY_ATTR_ID] = { NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) /* TODO handle it as for_each_nested and NLA_FLAG? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) [NL802154_KEY_ATTR_USAGE_FRAMES] = { NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) /* TODO handle it as for_each_nested, not static array? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) [NL802154_KEY_ATTR_USAGE_CMDS] = { .len = NL802154_CMD_FRAME_NR_IDS / 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) [NL802154_KEY_ATTR_BYTES] = { .len = NL802154_KEY_SIZE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) static int nl802154_add_llsec_key(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) struct nlattr *attrs[NL802154_KEY_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) struct ieee802154_llsec_key key = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) struct ieee802154_llsec_key_id id = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) u32 commands[NL802154_CMD_FRAME_NR_IDS / 32] = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) if (!info->attrs[NL802154_ATTR_SEC_KEY] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) nla_parse_nested_deprecated(attrs, NL802154_KEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_KEY], nl802154_key_policy, info->extack))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) if (!attrs[NL802154_KEY_ATTR_USAGE_FRAMES] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) !attrs[NL802154_KEY_ATTR_BYTES])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) if (ieee802154_llsec_parse_key_id(attrs[NL802154_KEY_ATTR_ID], &id) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) key.frame_types = nla_get_u8(attrs[NL802154_KEY_ATTR_USAGE_FRAMES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) if (key.frame_types > BIT(NL802154_FRAME_MAX) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) ((key.frame_types & BIT(NL802154_FRAME_CMD)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) !attrs[NL802154_KEY_ATTR_USAGE_CMDS]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) if (attrs[NL802154_KEY_ATTR_USAGE_CMDS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) /* TODO for each nested */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) nla_memcpy(commands, attrs[NL802154_KEY_ATTR_USAGE_CMDS],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) NL802154_CMD_FRAME_NR_IDS / 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) /* TODO understand the -EINVAL logic here? last condition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) if (commands[0] || commands[1] || commands[2] || commands[3] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) commands[4] || commands[5] || commands[6] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) commands[7] > BIT(NL802154_CMD_FRAME_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) key.cmd_frame_ids = commands[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) key.cmd_frame_ids = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) nla_memcpy(key.key, attrs[NL802154_KEY_ATTR_BYTES], NL802154_KEY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) if (ieee802154_llsec_parse_key_id(attrs[NL802154_KEY_ATTR_ID], &id) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) return rdev_add_llsec_key(rdev, wpan_dev, &id, &key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) static int nl802154_del_llsec_key(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) struct nlattr *attrs[NL802154_KEY_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) struct ieee802154_llsec_key_id id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) if (!info->attrs[NL802154_ATTR_SEC_KEY] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) nla_parse_nested_deprecated(attrs, NL802154_KEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_KEY], nl802154_key_policy, info->extack))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) if (ieee802154_llsec_parse_key_id(attrs[NL802154_KEY_ATTR_ID], &id) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) return rdev_del_llsec_key(rdev, wpan_dev, &id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) static int nl802154_send_device(struct sk_buff *msg, u32 cmd, u32 portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) u32 seq, int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) struct cfg802154_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) const struct ieee802154_llsec_device *dev_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) struct nlattr *nl_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) nl_device = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) if (!nl_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) if (nla_put_u32(msg, NL802154_DEV_ATTR_FRAME_COUNTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) dev_desc->frame_counter) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) nla_put_le16(msg, NL802154_DEV_ATTR_PAN_ID, dev_desc->pan_id) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) nla_put_le16(msg, NL802154_DEV_ATTR_SHORT_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) dev_desc->short_addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) nla_put_le64(msg, NL802154_DEV_ATTR_EXTENDED_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) dev_desc->hwaddr, NL802154_DEV_ATTR_PAD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) nla_put_u8(msg, NL802154_DEV_ATTR_SECLEVEL_EXEMPT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) dev_desc->seclevel_exempt) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) nla_put_u32(msg, NL802154_DEV_ATTR_KEY_MODE, dev_desc->key_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) nla_nest_end(msg, nl_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) nl802154_dump_llsec_dev(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) struct cfg802154_registered_device *rdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) struct ieee802154_llsec_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) struct ieee802154_llsec_table *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) struct wpan_dev *wpan_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) err = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) if (!wpan_dev->netdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) rdev_lock_llsec_table(rdev, wpan_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) rdev_get_llsec_table(rdev, wpan_dev, &table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) /* TODO make it like station dump */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) if (cb->args[2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) list_for_each_entry(dev, &table->devices, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) if (nl802154_send_device(skb, NL802154_CMD_NEW_SEC_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) cb->nlh->nlmsg_seq, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) rdev, wpan_dev->netdev, dev) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) /* TODO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) rdev_unlock_llsec_table(rdev, wpan_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) cb->args[2] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) rdev_unlock_llsec_table(rdev, wpan_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) err = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) nl802154_finish_wpan_dev_dump(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) static const struct nla_policy nl802154_dev_policy[NL802154_DEV_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) [NL802154_DEV_ATTR_FRAME_COUNTER] = { NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) [NL802154_DEV_ATTR_PAN_ID] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) [NL802154_DEV_ATTR_SHORT_ADDR] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) [NL802154_DEV_ATTR_EXTENDED_ADDR] = { .type = NLA_U64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) [NL802154_DEV_ATTR_SECLEVEL_EXEMPT] = { NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) [NL802154_DEV_ATTR_KEY_MODE] = { NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) ieee802154_llsec_parse_device(struct nlattr *nla,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) struct ieee802154_llsec_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) struct nlattr *attrs[NL802154_DEV_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) if (!nla || nla_parse_nested_deprecated(attrs, NL802154_DEV_ATTR_MAX, nla, nl802154_dev_policy, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) memset(dev, 0, sizeof(*dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) if (!attrs[NL802154_DEV_ATTR_FRAME_COUNTER] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) !attrs[NL802154_DEV_ATTR_PAN_ID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) !attrs[NL802154_DEV_ATTR_SHORT_ADDR] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) !attrs[NL802154_DEV_ATTR_EXTENDED_ADDR] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) !attrs[NL802154_DEV_ATTR_SECLEVEL_EXEMPT] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) !attrs[NL802154_DEV_ATTR_KEY_MODE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) /* TODO be32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) dev->frame_counter = nla_get_u32(attrs[NL802154_DEV_ATTR_FRAME_COUNTER]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) dev->pan_id = nla_get_le16(attrs[NL802154_DEV_ATTR_PAN_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) dev->short_addr = nla_get_le16(attrs[NL802154_DEV_ATTR_SHORT_ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) /* TODO rename hwaddr to extended_addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) dev->hwaddr = nla_get_le64(attrs[NL802154_DEV_ATTR_EXTENDED_ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) dev->seclevel_exempt = nla_get_u8(attrs[NL802154_DEV_ATTR_SECLEVEL_EXEMPT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) dev->key_mode = nla_get_u32(attrs[NL802154_DEV_ATTR_KEY_MODE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) if (dev->key_mode > NL802154_DEVKEY_MAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) (dev->seclevel_exempt != 0 && dev->seclevel_exempt != 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) static int nl802154_add_llsec_dev(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) struct ieee802154_llsec_device dev_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) if (ieee802154_llsec_parse_device(info->attrs[NL802154_ATTR_SEC_DEVICE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) &dev_desc) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) return rdev_add_device(rdev, wpan_dev, &dev_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) static int nl802154_del_llsec_dev(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) struct nlattr *attrs[NL802154_DEV_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) __le64 extended_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) if (!info->attrs[NL802154_ATTR_SEC_DEVICE] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) nla_parse_nested_deprecated(attrs, NL802154_DEV_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_DEVICE], nl802154_dev_policy, info->extack))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) if (!attrs[NL802154_DEV_ATTR_EXTENDED_ADDR])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) extended_addr = nla_get_le64(attrs[NL802154_DEV_ATTR_EXTENDED_ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) return rdev_del_device(rdev, wpan_dev, extended_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) static int nl802154_send_devkey(struct sk_buff *msg, u32 cmd, u32 portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) u32 seq, int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) struct cfg802154_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) struct net_device *dev, __le64 extended_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) const struct ieee802154_llsec_device_key *devkey)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) struct nlattr *nl_devkey, *nl_key_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) nl_devkey = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_DEVKEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) if (!nl_devkey)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) if (nla_put_le64(msg, NL802154_DEVKEY_ATTR_EXTENDED_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) extended_addr, NL802154_DEVKEY_ATTR_PAD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) nla_put_u32(msg, NL802154_DEVKEY_ATTR_FRAME_COUNTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) devkey->frame_counter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) nl_key_id = nla_nest_start_noflag(msg, NL802154_DEVKEY_ATTR_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) if (!nl_key_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) if (ieee802154_llsec_send_key_id(msg, &devkey->key_id) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) nla_nest_end(msg, nl_key_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) nla_nest_end(msg, nl_devkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) nl802154_dump_llsec_devkey(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) struct cfg802154_registered_device *rdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) struct ieee802154_llsec_device_key *kpos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) struct ieee802154_llsec_device *dpos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) struct ieee802154_llsec_table *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) struct wpan_dev *wpan_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) err = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) if (!wpan_dev->netdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) rdev_lock_llsec_table(rdev, wpan_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) rdev_get_llsec_table(rdev, wpan_dev, &table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) /* TODO make it like station dump */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) if (cb->args[2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) /* TODO look if remove devkey and do some nested attribute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) list_for_each_entry(dpos, &table->devices, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) list_for_each_entry(kpos, &dpos->keys, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) if (nl802154_send_devkey(skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) NL802154_CMD_NEW_SEC_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) cb->nlh->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) NLM_F_MULTI, rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) wpan_dev->netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) dpos->hwaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) kpos) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) /* TODO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) rdev_unlock_llsec_table(rdev, wpan_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) cb->args[2] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) rdev_unlock_llsec_table(rdev, wpan_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) err = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) nl802154_finish_wpan_dev_dump(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) static const struct nla_policy nl802154_devkey_policy[NL802154_DEVKEY_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) [NL802154_DEVKEY_ATTR_FRAME_COUNTER] = { NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) [NL802154_DEVKEY_ATTR_EXTENDED_ADDR] = { NLA_U64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) [NL802154_DEVKEY_ATTR_ID] = { NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) static int nl802154_add_llsec_devkey(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) struct nlattr *attrs[NL802154_DEVKEY_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) struct ieee802154_llsec_device_key key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) __le64 extended_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) if (!info->attrs[NL802154_ATTR_SEC_DEVKEY] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) nla_parse_nested_deprecated(attrs, NL802154_DEVKEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_DEVKEY], nl802154_devkey_policy, info->extack) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) if (!attrs[NL802154_DEVKEY_ATTR_FRAME_COUNTER] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) !attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) /* TODO change key.id ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) if (ieee802154_llsec_parse_key_id(attrs[NL802154_DEVKEY_ATTR_ID],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) &key.key_id) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) /* TODO be32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) key.frame_counter = nla_get_u32(attrs[NL802154_DEVKEY_ATTR_FRAME_COUNTER]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) /* TODO change naming hwaddr -> extended_addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) * check unique identifier short+pan OR extended_addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) extended_addr = nla_get_le64(attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) return rdev_add_devkey(rdev, wpan_dev, extended_addr, &key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) static int nl802154_del_llsec_devkey(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) struct nlattr *attrs[NL802154_DEVKEY_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) struct ieee802154_llsec_device_key key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) __le64 extended_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) if (!info->attrs[NL802154_ATTR_SEC_DEVKEY] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) nla_parse_nested_deprecated(attrs, NL802154_DEVKEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_DEVKEY], nl802154_devkey_policy, info->extack))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) if (!attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) /* TODO change key.id ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) if (ieee802154_llsec_parse_key_id(attrs[NL802154_DEVKEY_ATTR_ID],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) &key.key_id) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) /* TODO change naming hwaddr -> extended_addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) * check unique identifier short+pan OR extended_addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) extended_addr = nla_get_le64(attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) return rdev_del_devkey(rdev, wpan_dev, extended_addr, &key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) static int nl802154_send_seclevel(struct sk_buff *msg, u32 cmd, u32 portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) u32 seq, int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) struct cfg802154_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) const struct ieee802154_llsec_seclevel *sl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) struct nlattr *nl_seclevel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) nl_seclevel = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_LEVEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) if (!nl_seclevel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) if (nla_put_u32(msg, NL802154_SECLEVEL_ATTR_FRAME, sl->frame_type) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) nla_put_u32(msg, NL802154_SECLEVEL_ATTR_LEVELS, sl->sec_levels) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) nla_put_u8(msg, NL802154_SECLEVEL_ATTR_DEV_OVERRIDE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) sl->device_override))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) if (sl->frame_type == NL802154_FRAME_CMD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) if (nla_put_u32(msg, NL802154_SECLEVEL_ATTR_CMD_FRAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) sl->cmd_frame_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) nla_nest_end(msg, nl_seclevel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) nl802154_dump_llsec_seclevel(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) struct cfg802154_registered_device *rdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) struct ieee802154_llsec_seclevel *sl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) struct ieee802154_llsec_table *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) struct wpan_dev *wpan_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) err = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) if (!wpan_dev->netdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) rdev_lock_llsec_table(rdev, wpan_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) rdev_get_llsec_table(rdev, wpan_dev, &table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) /* TODO make it like station dump */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) if (cb->args[2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) list_for_each_entry(sl, &table->security_levels, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) if (nl802154_send_seclevel(skb, NL802154_CMD_NEW_SEC_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) cb->nlh->nlmsg_seq, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) rdev, wpan_dev->netdev, sl) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) /* TODO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) rdev_unlock_llsec_table(rdev, wpan_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) cb->args[2] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) rdev_unlock_llsec_table(rdev, wpan_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) err = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) nl802154_finish_wpan_dev_dump(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) static const struct nla_policy nl802154_seclevel_policy[NL802154_SECLEVEL_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) [NL802154_SECLEVEL_ATTR_LEVELS] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) [NL802154_SECLEVEL_ATTR_FRAME] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) [NL802154_SECLEVEL_ATTR_CMD_FRAME] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) [NL802154_SECLEVEL_ATTR_DEV_OVERRIDE] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) llsec_parse_seclevel(struct nlattr *nla, struct ieee802154_llsec_seclevel *sl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) struct nlattr *attrs[NL802154_SECLEVEL_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) if (!nla || nla_parse_nested_deprecated(attrs, NL802154_SECLEVEL_ATTR_MAX, nla, nl802154_seclevel_policy, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) memset(sl, 0, sizeof(*sl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) if (!attrs[NL802154_SECLEVEL_ATTR_LEVELS] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) !attrs[NL802154_SECLEVEL_ATTR_FRAME] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) !attrs[NL802154_SECLEVEL_ATTR_DEV_OVERRIDE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) sl->sec_levels = nla_get_u8(attrs[NL802154_SECLEVEL_ATTR_LEVELS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) sl->frame_type = nla_get_u32(attrs[NL802154_SECLEVEL_ATTR_FRAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) sl->device_override = nla_get_u8(attrs[NL802154_SECLEVEL_ATTR_DEV_OVERRIDE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) if (sl->frame_type > NL802154_FRAME_MAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) (sl->device_override != 0 && sl->device_override != 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) if (sl->frame_type == NL802154_FRAME_CMD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) if (!attrs[NL802154_SECLEVEL_ATTR_CMD_FRAME])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) sl->cmd_frame_id = nla_get_u32(attrs[NL802154_SECLEVEL_ATTR_CMD_FRAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) if (sl->cmd_frame_id > NL802154_CMD_FRAME_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) static int nl802154_add_llsec_seclevel(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) struct ieee802154_llsec_seclevel sl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) if (llsec_parse_seclevel(info->attrs[NL802154_ATTR_SEC_LEVEL],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) &sl) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) return rdev_add_seclevel(rdev, wpan_dev, &sl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) static int nl802154_del_llsec_seclevel(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) struct cfg802154_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) struct ieee802154_llsec_seclevel sl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) if (!info->attrs[NL802154_ATTR_SEC_LEVEL] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) llsec_parse_seclevel(info->attrs[NL802154_ATTR_SEC_LEVEL],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) &sl) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) return rdev_del_seclevel(rdev, wpan_dev, &sl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) #define NL802154_FLAG_NEED_WPAN_PHY 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) #define NL802154_FLAG_NEED_NETDEV 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) #define NL802154_FLAG_NEED_RTNL 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) #define NL802154_FLAG_CHECK_NETDEV_UP 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) #define NL802154_FLAG_NEED_NETDEV_UP (NL802154_FLAG_NEED_NETDEV |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) NL802154_FLAG_CHECK_NETDEV_UP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) #define NL802154_FLAG_NEED_WPAN_DEV 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) #define NL802154_FLAG_NEED_WPAN_DEV_UP (NL802154_FLAG_NEED_WPAN_DEV |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) NL802154_FLAG_CHECK_NETDEV_UP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) static int nl802154_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) struct cfg802154_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) struct wpan_dev *wpan_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) bool rtnl = ops->internal_flags & NL802154_FLAG_NEED_RTNL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) if (rtnl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) if (ops->internal_flags & NL802154_FLAG_NEED_WPAN_PHY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) rdev = cfg802154_get_dev_from_info(genl_info_net(info), info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) if (IS_ERR(rdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) if (rtnl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) return PTR_ERR(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) info->user_ptr[0] = rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) } else if (ops->internal_flags & NL802154_FLAG_NEED_NETDEV ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) ops->internal_flags & NL802154_FLAG_NEED_WPAN_DEV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) ASSERT_RTNL();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) wpan_dev = __cfg802154_wpan_dev_from_attrs(genl_info_net(info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) info->attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) if (IS_ERR(wpan_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) if (rtnl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) return PTR_ERR(wpan_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) dev = wpan_dev->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) rdev = wpan_phy_to_rdev(wpan_dev->wpan_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) if (ops->internal_flags & NL802154_FLAG_NEED_NETDEV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) if (rtnl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) info->user_ptr[1] = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) info->user_ptr[1] = wpan_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) if (dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) if (ops->internal_flags & NL802154_FLAG_CHECK_NETDEV_UP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) !netif_running(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) if (rtnl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) return -ENETDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) dev_hold(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) info->user_ptr[0] = rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) static void nl802154_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) if (info->user_ptr[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) if (ops->internal_flags & NL802154_FLAG_NEED_WPAN_DEV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) struct wpan_dev *wpan_dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) if (wpan_dev->netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) dev_put(wpan_dev->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) dev_put(info->user_ptr[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) if (ops->internal_flags & NL802154_FLAG_NEED_RTNL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) static const struct genl_ops nl802154_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) .cmd = NL802154_CMD_GET_WPAN_PHY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) .validate = GENL_DONT_VALIDATE_STRICT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) GENL_DONT_VALIDATE_DUMP_STRICT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) .doit = nl802154_get_wpan_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) .dumpit = nl802154_dump_wpan_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) .done = nl802154_dump_wpan_phy_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) /* can be retrieved by unprivileged users */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) .cmd = NL802154_CMD_GET_INTERFACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) .doit = nl802154_get_interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) .dumpit = nl802154_dump_interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) /* can be retrieved by unprivileged users */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) .internal_flags = NL802154_FLAG_NEED_WPAN_DEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) .cmd = NL802154_CMD_NEW_INTERFACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) .doit = nl802154_new_interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) .cmd = NL802154_CMD_DEL_INTERFACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) .doit = nl802154_del_interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) .internal_flags = NL802154_FLAG_NEED_WPAN_DEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) .cmd = NL802154_CMD_SET_CHANNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) .doit = nl802154_set_channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) .cmd = NL802154_CMD_SET_CCA_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) .doit = nl802154_set_cca_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) .cmd = NL802154_CMD_SET_CCA_ED_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) .doit = nl802154_set_cca_ed_level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) .cmd = NL802154_CMD_SET_TX_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) .doit = nl802154_set_tx_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) .cmd = NL802154_CMD_SET_WPAN_PHY_NETNS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) .doit = nl802154_wpan_phy_netns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) .cmd = NL802154_CMD_SET_PAN_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) .doit = nl802154_set_pan_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) .cmd = NL802154_CMD_SET_SHORT_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) .doit = nl802154_set_short_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) .cmd = NL802154_CMD_SET_BACKOFF_EXPONENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) .doit = nl802154_set_backoff_exponent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) .cmd = NL802154_CMD_SET_MAX_CSMA_BACKOFFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) .doit = nl802154_set_max_csma_backoffs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) .cmd = NL802154_CMD_SET_MAX_FRAME_RETRIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) .doit = nl802154_set_max_frame_retries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) .cmd = NL802154_CMD_SET_LBT_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) .doit = nl802154_set_lbt_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) .cmd = NL802154_CMD_SET_ACKREQ_DEFAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) .doit = nl802154_set_ackreq_default,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) .cmd = NL802154_CMD_SET_SEC_PARAMS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) .doit = nl802154_set_llsec_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) .cmd = NL802154_CMD_GET_SEC_KEY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) .validate = GENL_DONT_VALIDATE_STRICT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) GENL_DONT_VALIDATE_DUMP_STRICT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) /* TODO .doit by matching key id? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) .dumpit = nl802154_dump_llsec_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) .cmd = NL802154_CMD_NEW_SEC_KEY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) .doit = nl802154_add_llsec_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) .cmd = NL802154_CMD_DEL_SEC_KEY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) .doit = nl802154_del_llsec_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) /* TODO unique identifier must short+pan OR extended_addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) .cmd = NL802154_CMD_GET_SEC_DEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) .validate = GENL_DONT_VALIDATE_STRICT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) GENL_DONT_VALIDATE_DUMP_STRICT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) /* TODO .doit by matching extended_addr? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) .dumpit = nl802154_dump_llsec_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) .cmd = NL802154_CMD_NEW_SEC_DEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) .doit = nl802154_add_llsec_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) .cmd = NL802154_CMD_DEL_SEC_DEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) .doit = nl802154_del_llsec_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) /* TODO remove complete devkey, put it as nested? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) .cmd = NL802154_CMD_GET_SEC_DEVKEY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) .validate = GENL_DONT_VALIDATE_STRICT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) GENL_DONT_VALIDATE_DUMP_STRICT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) /* TODO doit by matching ??? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) .dumpit = nl802154_dump_llsec_devkey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) .cmd = NL802154_CMD_NEW_SEC_DEVKEY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) .doit = nl802154_add_llsec_devkey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) .cmd = NL802154_CMD_DEL_SEC_DEVKEY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) .doit = nl802154_del_llsec_devkey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) .cmd = NL802154_CMD_GET_SEC_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) .validate = GENL_DONT_VALIDATE_STRICT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) GENL_DONT_VALIDATE_DUMP_STRICT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) /* TODO .doit by matching frame_type? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) .dumpit = nl802154_dump_llsec_seclevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) .cmd = NL802154_CMD_NEW_SEC_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) .doit = nl802154_add_llsec_seclevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) .cmd = NL802154_CMD_DEL_SEC_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) /* TODO match frame_type only? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) .doit = nl802154_del_llsec_seclevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) .internal_flags = NL802154_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) NL802154_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) static struct genl_family nl802154_fam __ro_after_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) .name = NL802154_GENL_NAME, /* have users key off the name instead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) .hdrsize = 0, /* no private header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) .version = 1, /* no particular meaning now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) .maxattr = NL802154_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) .policy = nl802154_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) .netnsok = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) .pre_doit = nl802154_pre_doit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) .post_doit = nl802154_post_doit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) .ops = nl802154_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) .n_ops = ARRAY_SIZE(nl802154_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) .mcgrps = nl802154_mcgrps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) .n_mcgrps = ARRAY_SIZE(nl802154_mcgrps),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) /* initialisation/exit functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) int __init nl802154_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) return genl_register_family(&nl802154_fam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) void nl802154_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) genl_unregister_family(&nl802154_fam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) }