Thread (24 messages) 24 messages, 3 authors, 2023-09-01

Re: [PATCH wpan-next 04/11] mac802154: Handle associating

From: Alexander Aring <aahringo@redhat.com>
Date: 2023-07-04 11:34:31

Hi,

On Sat, Jun 3, 2023 at 6:09 AM Alexander Aring [off-list ref] wrote:
Hi,

On Thu, Jun 1, 2023 at 11:50 AM Miquel Raynal [off-list ref] wrote:
quoted
Joining a PAN officially goes by associating with a coordinator. This
coordinator may have been discovered thanks to the beacons it sent in
the past. Add support to the MAC layer for these associations, which
require:
- Sending an association request
- Receiving an association response

The association response contains the association status, eventually a
reason if the association was unsuccessful, and finally a short address
that we should use for intra-PAN communication from now on, if we
required one (which is the default, and not yet configurable).

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 include/linux/ieee802154.h      |   1 +
 include/net/cfg802154.h         |   1 +
 include/net/ieee802154_netdev.h |   5 ++
 net/ieee802154/core.c           |  14 ++++
 net/mac802154/cfg.c             |  72 ++++++++++++++++++
 net/mac802154/ieee802154_i.h    |  19 +++++
 net/mac802154/main.c            |   2 +
 net/mac802154/rx.c              |   9 +++
 net/mac802154/scan.c            | 127 ++++++++++++++++++++++++++++++++
 9 files changed, 250 insertions(+)
diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h
index 140f61ec0f5f..c72bd76cac1b 100644
--- a/include/linux/ieee802154.h
+++ b/include/linux/ieee802154.h
@@ -37,6 +37,7 @@
                                         IEEE802154_FCS_LEN)

 #define IEEE802154_PAN_ID_BROADCAST    0xffff
+#define IEEE802154_ADDR_LONG_BROADCAST 0xffffffffffffffffULL
 #define IEEE802154_ADDR_SHORT_BROADCAST        0xffff
 #define IEEE802154_ADDR_SHORT_UNSPEC   0xfffe
diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index 3b9d65455b9a..dd0964d351cd 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -502,6 +502,7 @@ struct wpan_dev {
        struct mutex association_lock;
        struct ieee802154_pan_device *parent;
        struct list_head children;
+       unsigned int association_generation;
 };

 #define to_phy(_dev)   container_of(_dev, struct wpan_phy, dev)
diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
index ca8c827d0d7f..e26ffd079556 100644
--- a/include/net/ieee802154_netdev.h
+++ b/include/net/ieee802154_netdev.h
@@ -149,6 +149,11 @@ struct ieee802154_assoc_req_pl {
 #endif
 } __packed;

+struct ieee802154_assoc_resp_pl {
+       __le16 short_addr;
+       u8 status;
+} __packed;
+
 enum ieee802154_frame_version {
        IEEE802154_2003_STD,
        IEEE802154_2006_STD,
diff --git a/net/ieee802154/core.c b/net/ieee802154/core.c
index cd69bdbfd59f..8bf01bb7e858 100644
--- a/net/ieee802154/core.c
+++ b/net/ieee802154/core.c
@@ -198,6 +198,18 @@ void wpan_phy_free(struct wpan_phy *phy)
 }
 EXPORT_SYMBOL(wpan_phy_free);

+static void cfg802154_free_peer_structures(struct wpan_dev *wpan_dev)
+{
+       mutex_lock(&wpan_dev->association_lock);
+
+       if (wpan_dev->parent)
+               kfree(wpan_dev->parent);
+
+       wpan_dev->association_generation++;
+
+       mutex_unlock(&wpan_dev->association_lock);
+}
+
 int cfg802154_switch_netns(struct cfg802154_registered_device *rdev,
                           struct net *net)
 {
@@ -293,6 +305,8 @@ static int cfg802154_netdev_notifier_call(struct notifier_block *nb,
                rdev->opencount++;
                break;
        case NETDEV_UNREGISTER:
+               cfg802154_free_peer_structures(wpan_dev);
+
I think the comment below is not relevant here, but I have also no
idea if this is still the case.
quoted
                /* It is possible to get NETDEV_UNREGISTER
                 * multiple times. To detect that, check
                 * that the interface is still on the list
diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c
index 5c3cb019f751..89112d2bcee7 100644
--- a/net/mac802154/cfg.c
+++ b/net/mac802154/cfg.c
@@ -315,6 +315,77 @@ static int mac802154_stop_beacons(struct wpan_phy *wpan_phy,
        return mac802154_stop_beacons_locked(local, sdata);
 }

+static int mac802154_associate(struct wpan_phy *wpan_phy,
+                              struct wpan_dev *wpan_dev,
+                              struct ieee802154_addr *coord)
+{
+       struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
+       u64 ceaddr = swab64((__force u64)coord->extended_addr);
+       struct ieee802154_sub_if_data *sdata;
+       struct ieee802154_pan_device *parent;
+       __le16 short_addr;
+       int ret;
+
+       ASSERT_RTNL();
+
+       sdata = IEEE802154_WPAN_DEV_TO_SUB_IF(wpan_dev);
+
+       if (wpan_dev->parent) {
+               dev_err(&sdata->dev->dev,
+                       "Device %8phC is already associated\n", &ceaddr);
+               return -EPERM;
+       }
+
+       parent = kzalloc(sizeof(*parent), GFP_KERNEL);
+       if (!parent)
+               return -ENOMEM;
+
+       parent->pan_id = coord->pan_id;
+       parent->mode = coord->mode;
+       if (parent->mode == IEEE802154_SHORT_ADDRESSING) {
+               parent->short_addr = coord->short_addr;
+               parent->extended_addr = cpu_to_le64(IEEE802154_ADDR_LONG_BROADCAST);
There is no IEEE802154_ADDR_LONG_BROADCAST (extended address) address.
The broadcast address is always a short address 0xffff. (Talkin about
destination addresses).

Just to clarify we can have here two different types/length of mac
addresses being used, whereas the extended address is always present.
We have the monitor interface set to an invalid extended address
0x0...0 (talking about source address) which is a reserved EUI64 (what
long/extended address is) address, 0xffff...ffff is also being
reserved. Monitors get their address from the socket interface.

If there is a parent, an extended address is always present and known.
I want to weaken this, we can also have only the short address of the
neighbor. But it depends on assoc/deassoc, I would think the extended
address should be known. If you look on air and make per neighbor
stats... you can see a neighbor with either a short or extended
address being used. Map them to one neighbor if using a short address
is only possible if you know the mapping... (but this is so far I see
not the case here).

We need some kind of policy here, but with assoc/deassoc we should
always know this mapping.

- Alex
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help