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 0xfffediff --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 listdiff --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