ieee820154: add pan_id setting support
authorAlexander Aring <alex.aring@gmail.com>
Wed, 12 Nov 2014 02:36:57 +0000 (03:36 +0100)
committerMarcel Holtmann <marcel@holtmann.org>
Wed, 12 Nov 2014 04:10:39 +0000 (05:10 +0100)
This patch adds support for setting pan_id via nl802154 framework.
Adding a comment because setting 0xffff as pan_id seems to be valid
setting. The pan_id 0xffff as source pan is invalid. I am not sure now
about this setting but for the current netlink interface this is an
invalid setting, so we do the same now. Maybe we need to change that
when we have coordinator support and association support.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
include/linux/ieee802154.h
include/net/cfg802154.h
net/ieee802154/nl802154.c
net/ieee802154/rdev-ops.h
net/mac802154/cfg.c

index d043449a079d190ff87a15748a3f54466a755be0..d40379876b8479b8a7dcf9d3eaa337e57d87b52a 100644 (file)
@@ -30,6 +30,8 @@
 #define IEEE802154_MTU                 127
 #define IEEE802154_MIN_PSDU_LEN                5
 
+#define IEEE802154_PAN_ID_BROADCAST    0xffff
+
 #define IEEE802154_EXTENDED_ADDR_LEN   8
 
 #define IEEE802154_FC_TYPE_BEACON      0x0     /* Frame is beacon */
index 391fdb37208d5ead3d4b48740d1213116ecb7729..d07b0726b28540c7d80fe73d0630b3a03f19f817 100644 (file)
@@ -38,6 +38,8 @@ struct cfg802154_ops {
        void    (*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy,
                                               struct net_device *dev);
        int     (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel);
+       int     (*set_pan_id)(struct wpan_phy *wpan_phy,
+                             struct wpan_dev *wpan_dev, u16 pan_id);
 };
 
 struct wpan_phy {
index d8ef2c8a182fae2e0a6390d6ac56135865c53fca..88cd1293283ae79576c4d747e9c9c1962803f8d9 100644 (file)
@@ -570,6 +570,29 @@ static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info)
        return rdev_set_channel(rdev, page, channel);
 }
 
+static int nl802154_set_pan_id(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg802154_registered_device *rdev = info->user_ptr[0];
+       struct net_device *dev = info->user_ptr[1];
+       struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
+       u16 pan_id;
+
+       /* conflict here while tx/rx calls */
+       if (netif_running(dev))
+               return -EBUSY;
+
+       /* don't change address fields on monitor */
+       if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
+               return -EINVAL;
+
+       if (!info->attrs[NL802154_ATTR_PAN_ID])
+               return -EINVAL;
+
+       pan_id = nla_get_u16(info->attrs[NL802154_ATTR_PAN_ID]);
+
+       return rdev_set_pan_id(rdev, wpan_dev, pan_id);
+}
+
 #define NL802154_FLAG_NEED_WPAN_PHY    0x01
 #define NL802154_FLAG_NEED_NETDEV      0x02
 #define NL802154_FLAG_NEED_RTNL                0x04
@@ -688,6 +711,14 @@ static const struct genl_ops nl802154_ops[] = {
                .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
                                  NL802154_FLAG_NEED_RTNL,
        },
+       {
+               .cmd = NL802154_CMD_SET_PAN_ID,
+               .doit = nl802154_set_pan_id,
+               .policy = nl802154_policy,
+               .flags = GENL_ADMIN_PERM,
+               .internal_flags = NL802154_FLAG_NEED_NETDEV |
+                                 NL802154_FLAG_NEED_RTNL,
+       },
 };
 
 /* initialisation/exit functions */
index 8a3b0eb4e02696f0068ed97f23e399987738c1e2..4115ea264fd56353bba9037fce60cf986b78a376 100644 (file)
@@ -27,4 +27,11 @@ rdev_set_channel(struct cfg802154_registered_device *rdev, const u8 page,
        return rdev->ops->set_channel(&rdev->wpan_phy, page, channel);
 }
 
+static inline int
+rdev_set_pan_id(struct cfg802154_registered_device *rdev,
+               struct wpan_dev *wpan_dev, u16 pan_id)
+{
+       return rdev->ops->set_pan_id(&rdev->wpan_phy, wpan_dev, pan_id);
+}
+
 #endif /* __CFG802154_RDEV_OPS */
index 9d5b1895c752ed9317dffdf2f129eeed34187bfc..db6e5e981a835e7519dc557cc87fc52e59b11d44 100644 (file)
@@ -64,8 +64,28 @@ ieee802154_set_channel(struct wpan_phy *wpan_phy, const u8 page,
        return ret;
 }
 
+static int ieee802154_set_pan_id(struct wpan_phy *wpan_phy,
+                                struct wpan_dev *wpan_dev, const u16 pan_id)
+{
+       ASSERT_RTNL();
+
+       /* TODO
+        * I am not sure about to check here on broadcast pan_id.
+        * Broadcast is a valid setting, comment from 802.15.4:
+        * If this value is 0xffff, the device is not associated.
+        *
+        * This could useful to simple deassociate an device.
+        */
+       if (pan_id == IEEE802154_PAN_ID_BROADCAST)
+               return -EINVAL;
+
+       wpan_dev->pan_id = cpu_to_le16(pan_id);
+       return 0;
+}
+
 const struct cfg802154_ops mac802154_config_ops = {
        .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated,
        .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated,
        .set_channel = ieee802154_set_channel,
+       .set_pan_id = ieee802154_set_pan_id,
 };