linux-wpan.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing
@ 2022-07-01 14:30 Miquel Raynal
  2022-07-01 14:30 ` [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces Miquel Raynal
                   ` (20 more replies)
  0 siblings, 21 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

Hello,

After a few exchanges about inter-PAN management with Alexander, it was
decided that most of this series would be dropped, because the kernel
should in the end not really care about keeping a local copy of the
discovered coordinators, this is userspace job.

So here is a "first" version of the scanning series which hopefully
meets the main requirements discussed the past days on the mailing
list. I know it is rather big, but there are a few very trivial patches
there, so here is how it is built:

* net: mac802154: Allow the creation of coordinator interfaces

  Beaconing must be reserved to coordinator interfaces, so we must
  support the creation of these interfaces in the mac layer.

* net: ieee802154: Advertize coordinators discovery
* net: ieee802154: Handle coordinators discovery
 
  Introduction of a user interface and then a cfg802154 interface for
  coordinators discovery and advertisement.

* net: ieee802154: Define frame types
* net: ieee802154: Add support for user scanning requests
* net: ieee802154: Define a beacon frame header
* net: mac802154: Prepare forcing specific symbol duration
* net: mac802154: Introduce a global device lock
* net: mac802154: Handle passive scanning

  User requests to scan and MAC handling of these requests.

* net: ieee802154: Add support for user beaconing requests
* net: mac802154: Handle basic beaconing

  User requests to send beacons and MAC handling of these requests.

* net: ieee802154: Add support for user active scan requests
* net: mac802154: Handle active scanning

  User requests to scan actively and MAC handling of these requests.

* net: ieee802154: Add support for allowing to answer BEACON_REQ
* net: mac802154: Handle received BEACON_REQ

  User requests to answer BEACON_RQ and MAC handling of these requests.

* net: ieee802154: Handle limited devices with only datagram support
* ieee802154: ca8210: Flag the driver as being limited

  This is a result of a previous review from Alexander, which pointed
  that the hardMAC ca8210 would not support the scanning operations, so
  it is flagged as limited.

* ieee802154: hwsim: Do not check the rtnl
* ieee802154: hwsim: Allow devices to be coordinators

  And finally these two patches are there to allow using hwsim to
  validate the series.

The corresponding userspace code will follow.

The series lacks support for forwarding association requests to the user
and waiting for feedback before accepting the device. This can be added
later on top of this work and is not necessary right now.

All of this is based on the initial work from David Girault and Romuald
Despres, they are often credited as Co-developpers.

Thanks,
Miquèl

David Girault (1):
  net: ieee802154: Trace the registration of new PANs

Miquel Raynal (19):
  net: mac802154: Allow the creation of coordinator interfaces
  net: ieee802154: Advertize coordinators discovery
  net: ieee802154: Handle coordinators discovery
  net: ieee802154: Define frame types
  net: ieee802154: Add support for user scanning requests
  net: ieee802154: Define a beacon frame header
  net: mac802154: Prepare forcing specific symbol duration
  net: mac802154: Introduce a global device lock
  net: mac802154: Handle passive scanning
  net: ieee802154: Add support for user beaconing requests
  net: mac802154: Handle basic beaconing
  net: ieee802154: Add support for user active scan requests
  net: mac802154: Handle active scanning
  net: ieee802154: Add support for allowing to answer BEACON_REQ
  net: mac802154: Handle received BEACON_REQ
  net: ieee802154: Handle limited devices with only datagram support
  ieee802154: ca8210: Flag the driver as being limited
  ieee802154: hwsim: Do not check the rtnl
  ieee802154: hwsim: Allow devices to be coordinators

 drivers/net/ieee802154/ca8210.c          |   3 +-
 drivers/net/ieee802154/mac802154_hwsim.c |   4 +-
 include/linux/ieee802154.h               |   7 +
 include/net/cfg802154.h                  |  97 ++++-
 include/net/ieee802154_netdev.h          |  89 +++++
 include/net/nl802154.h                   |  93 +++++
 net/ieee802154/Makefile                  |   2 +-
 net/ieee802154/core.c                    |   2 +
 net/ieee802154/header_ops.c              |  69 ++++
 net/ieee802154/nl802154.c                | 402 ++++++++++++++++++++
 net/ieee802154/nl802154.h                |   7 +
 net/ieee802154/pan.c                     | 114 ++++++
 net/ieee802154/rdev-ops.h                |  56 +++
 net/ieee802154/trace.h                   |  86 +++++
 net/mac802154/Makefile                   |   2 +-
 net/mac802154/cfg.c                      |  76 +++-
 net/mac802154/ieee802154_i.h             |  70 ++++
 net/mac802154/iface.c                    |  30 +-
 net/mac802154/main.c                     |  29 +-
 net/mac802154/rx.c                       | 113 +++++-
 net/mac802154/scan.c                     | 462 +++++++++++++++++++++++
 net/mac802154/tx.c                       |  12 +-
 22 files changed, 1793 insertions(+), 32 deletions(-)
 create mode 100644 net/ieee802154/pan.c
 create mode 100644 net/mac802154/scan.c

-- 
2.34.1


^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-06  1:51   ` Alexander Aring
  2022-07-01 14:30 ` [PATCH wpan-next 02/20] net: ieee802154: Advertize coordinators discovery Miquel Raynal
                   ` (19 subsequent siblings)
  20 siblings, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

As a first strep in introducing proper PAN management and association,
we need to be able to create coordinator interfaces which might act as
coordinator or PAN coordinator.

Hence, let's add the minimum support to allow the creation of these
interfaces. This might be restrained and improved later.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 net/mac802154/iface.c | 14 ++++++++------
 net/mac802154/rx.c    |  2 +-
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
index 500ed1b81250..7ac0c5685d3f 100644
--- a/net/mac802154/iface.c
+++ b/net/mac802154/iface.c
@@ -273,13 +273,13 @@ ieee802154_check_concurrent_iface(struct ieee802154_sub_if_data *sdata,
 		if (nsdata != sdata && ieee802154_sdata_running(nsdata)) {
 			int ret;
 
-			/* TODO currently we don't support multiple node types
-			 * we need to run skb_clone at rx path. Check if there
-			 * exist really an use case if we need to support
-			 * multiple node types at the same time.
+			/* TODO currently we don't support multiple node/coord
+			 * types we need to run skb_clone at rx path. Check if
+			 * there exist really an use case if we need to support
+			 * multiple node/coord types at the same time.
 			 */
-			if (wpan_dev->iftype == NL802154_IFTYPE_NODE &&
-			    nsdata->wpan_dev.iftype == NL802154_IFTYPE_NODE)
+			if (wpan_dev->iftype != NL802154_IFTYPE_MONITOR &&
+			    nsdata->wpan_dev.iftype != NL802154_IFTYPE_MONITOR)
 				return -EBUSY;
 
 			/* check all phy mac sublayer settings are the same.
@@ -577,6 +577,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
 	wpan_dev->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
 
 	switch (type) {
+	case NL802154_IFTYPE_COORD:
 	case NL802154_IFTYPE_NODE:
 		ieee802154_be64_to_le64(&wpan_dev->extended_addr,
 					sdata->dev->dev_addr);
@@ -636,6 +637,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
 	ieee802154_le64_to_be64(ndev->perm_addr,
 				&local->hw.phy->perm_extended_addr);
 	switch (type) {
+	case NL802154_IFTYPE_COORD:
 	case NL802154_IFTYPE_NODE:
 		ndev->type = ARPHRD_IEEE802154;
 		if (ieee802154_is_valid_extended_unicast_addr(extended_addr)) {
diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
index b8ce84618a55..39459d8d787a 100644
--- a/net/mac802154/rx.c
+++ b/net/mac802154/rx.c
@@ -203,7 +203,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
 	}
 
 	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
-		if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
+		if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
 			continue;
 
 		if (!ieee802154_sdata_running(sdata))
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 02/20] net: ieee802154: Advertize coordinators discovery
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
  2022-07-01 14:30 ` [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-01 14:30 ` [PATCH wpan-next 03/20] net: ieee802154: Handle " Miquel Raynal
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

Let's introduce the basics for advertizing discovered PANs and
coordinators, which is:
- A new "scan" netlink message group.
- A couple of netlink command/attribute.
- The main netlink helper to send a netlink message with all the
  necessary information to forward the main information to the user.

Co-developed-by: David Girault <david.girault@qorvo.com>
Signed-off-by: David Girault <david.girault@qorvo.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 include/net/cfg802154.h   |  20 ++++++++
 include/net/nl802154.h    |  43 ++++++++++++++++
 net/ieee802154/nl802154.c | 102 ++++++++++++++++++++++++++++++++++++++
 net/ieee802154/nl802154.h |   3 ++
 4 files changed, 168 insertions(+)

diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index 04b996895fc1..1f1b275dcabd 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -255,6 +255,26 @@ struct ieee802154_addr {
 	};
 };
 
+/**
+ * struct ieee802154_coord_desc - Coordinator descriptor
+ * @coord: PAN ID and coordinator address
+ * @page: page this coordinator is using
+ * @channel: channel this coordinator is using
+ * @superframe_spec: SuperFrame specification as received
+ * @link_quality: link quality indicator at which the beacon was received
+ * @gts_permit: the coordinator accepts GTS requests
+ * @node: list item
+ */
+struct ieee802154_coord_desc {
+	struct ieee802154_addr *addr;
+	u8 page;
+	u8 channel;
+	u16 superframe_spec;
+	u8 link_quality;
+	bool gts_permit;
+	struct list_head node;
+};
+
 struct ieee802154_llsec_key_id {
 	u8 mode;
 	u8 id;
diff --git a/include/net/nl802154.h b/include/net/nl802154.h
index 145acb8f2509..dba05553d106 100644
--- a/include/net/nl802154.h
+++ b/include/net/nl802154.h
@@ -58,6 +58,8 @@ enum nl802154_commands {
 
 	NL802154_CMD_SET_WPAN_PHY_NETNS,
 
+	NL802154_CMD_NEW_COORDINATOR,
+
 	/* add new commands above here */
 
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
@@ -133,6 +135,8 @@ enum nl802154_attrs {
 	NL802154_ATTR_PID,
 	NL802154_ATTR_NETNS_FD,
 
+	NL802154_ATTR_COORDINATOR,
+
 	/* add attributes here, update the policy in nl802154.c */
 
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
@@ -218,6 +222,45 @@ enum nl802154_wpan_phy_capability_attr {
 	NL802154_CAP_ATTR_MAX = __NL802154_CAP_ATTR_AFTER_LAST - 1
 };
 
+/**
+ * enum nl802154_coord - Netlink attributes for a coord
+ *
+ * @__NL802154_COORD_INVALID: invalid
+ * @NL802154_COORD_PANID: PANID of the coordinator (2 bytes)
+ * @NL802154_COORD_ADDR: coordinator address, (8 bytes or 2 bytes)
+ * @NL802154_COORD_CHANNEL: channel number, related to @NL802154_COORD_PAGE (u8)
+ * @NL802154_COORD_PAGE: channel page, related to @NL802154_COORD_CHANNEL (u8)
+ * @NL802154_COORD_PREAMBLE_CODE: Preamble code used when the beacon was received,
+ *	this is PHY dependent and optional (u8)
+ * @NL802154_COORD_MEAN_PRF: Mean PRF used when the beacon was received,
+ *     this is PHY dependent and optional (u8)
+ * @NL802154_COORD_SUPERFRAME_SPEC: superframe specification of the PAN (u16)
+ * @NL802154_COORD_LINK_QUALITY: signal quality of beacon in unspecified units,
+ *	scaled to 0..255 (u8)
+ * @NL802154_COORD_GTS_PERMIT: set to true if GTS is permitted on this PAN
+ * @NL802154_COORD_PAYLOAD_DATA: binary data containing the raw data from the
+ *	frame payload, (only if beacon or probe response had data)
+ * @NL802154_COORD_PAD: attribute used for padding for 64-bit alignment
+ * @NL802154_COORD_MAX: highest coordinator attribute
+ */
+enum nl802154_coord {
+	__NL802154_COORD_INVALID,
+	NL802154_COORD_PANID,
+	NL802154_COORD_ADDR,
+	NL802154_COORD_CHANNEL,
+	NL802154_COORD_PAGE,
+	NL802154_COORD_PREAMBLE_CODE,
+	NL802154_COORD_MEAN_PRF,
+	NL802154_COORD_SUPERFRAME_SPEC,
+	NL802154_COORD_LINK_QUALITY,
+	NL802154_COORD_GTS_PERMIT,
+	NL802154_COORD_PAYLOAD_DATA,
+	NL802154_COORD_PAD,
+
+	/* keep last */
+	NL802154_COORD_MAX,
+};
+
 /**
  * enum nl802154_cca_modes - cca modes
  *
diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
index e0b072aecf0f..7c0aec10ef7f 100644
--- a/net/ieee802154/nl802154.c
+++ b/net/ieee802154/nl802154.c
@@ -26,10 +26,12 @@ static struct genl_family nl802154_fam;
 /* multicast groups */
 enum nl802154_multicast_groups {
 	NL802154_MCGRP_CONFIG,
+	NL802154_MCGRP_SCAN,
 };
 
 static const struct genl_multicast_group nl802154_mcgrps[] = {
 	[NL802154_MCGRP_CONFIG] = { .name = "config", },
+	[NL802154_MCGRP_SCAN] = { .name = "scan", },
 };
 
 /* returns ERR_PTR values */
@@ -216,6 +218,9 @@ static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = {
 
 	[NL802154_ATTR_PID] = { .type = NLA_U32 },
 	[NL802154_ATTR_NETNS_FD] = { .type = NLA_U32 },
+
+	[NL802154_ATTR_COORDINATOR] = { .type = NLA_NESTED },
+
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 	[NL802154_ATTR_SEC_ENABLED] = { .type = NLA_U8, },
 	[NL802154_ATTR_SEC_OUT_LEVEL] = { .type = NLA_U32, },
@@ -1281,6 +1286,103 @@ static int nl802154_wpan_phy_netns(struct sk_buff *skb, struct genl_info *info)
 	return err;
 }
 
+static int nl802154_prep_new_coord_msg(struct sk_buff *msg,
+				       struct cfg802154_registered_device *rdev,
+				       struct wpan_dev *wpan_dev,
+				       u32 portid, u32 seq, int flags, u8 cmd,
+				       struct ieee802154_coord_desc *desc)
+{
+	struct nlattr *nla;
+	void *hdr;
+
+	hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
+	if (!hdr)
+		return -ENOBUFS;
+
+	if (nla_put_u32(msg, NL802154_ATTR_WPAN_PHY, rdev->wpan_phy_idx))
+		goto nla_put_failure;
+
+	if (wpan_dev->netdev &&
+	    nla_put_u32(msg, NL802154_ATTR_IFINDEX, wpan_dev->netdev->ifindex))
+		goto nla_put_failure;
+
+	if (nla_put_u64_64bit(msg, NL802154_ATTR_WPAN_DEV,
+			      wpan_dev_id(wpan_dev), NL802154_ATTR_PAD))
+		goto nla_put_failure;
+
+	nla = nla_nest_start_noflag(msg, NL802154_ATTR_COORDINATOR);
+	if (!nla)
+		goto nla_put_failure;
+
+	if (nla_put(msg, NL802154_COORD_PANID, IEEE802154_PAN_ID_LEN,
+		    &desc->addr->pan_id))
+		goto nla_put_failure;
+
+	if (desc->addr->mode == IEEE802154_ADDR_SHORT) {
+		if (nla_put(msg, NL802154_COORD_ADDR,
+			    IEEE802154_SHORT_ADDR_LEN,
+			    &desc->addr->short_addr))
+			goto nla_put_failure;
+	} else {
+		if (nla_put(msg, NL802154_COORD_ADDR,
+			    IEEE802154_EXTENDED_ADDR_LEN,
+			    &desc->addr->extended_addr))
+			goto nla_put_failure;
+	}
+
+	if (nla_put_u8(msg, NL802154_COORD_CHANNEL, desc->channel))
+		goto nla_put_failure;
+
+	if (nla_put_u8(msg, NL802154_COORD_PAGE, desc->page))
+		goto nla_put_failure;
+
+	if (nla_put_u16(msg, NL802154_COORD_SUPERFRAME_SPEC,
+			desc->superframe_spec))
+		goto nla_put_failure;
+
+	if (nla_put_u8(msg, NL802154_COORD_LINK_QUALITY, desc->link_quality))
+		goto nla_put_failure;
+
+	if (desc->gts_permit && nla_put_flag(msg, NL802154_COORD_GTS_PERMIT))
+		goto nla_put_failure;
+
+	/* TODO: NL802154_COORD_PAYLOAD_DATA if any */
+
+	nla_nest_end(msg, nla);
+
+	genlmsg_end(msg, hdr);
+
+	return 0;
+
+ nla_put_failure:
+	genlmsg_cancel(msg, hdr);
+
+	return -EMSGSIZE;
+}
+
+int nl802154_advertise_new_coordinator(struct wpan_phy *wpan_phy,
+				       struct wpan_dev *wpan_dev,
+				       struct ieee802154_coord_desc *desc)
+{
+	struct cfg802154_registered_device *rdev = wpan_phy_to_rdev(wpan_phy);
+	struct sk_buff *msg;
+	int ret;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+	if (!msg)
+		return -ENOMEM;
+
+	ret = nl802154_prep_new_coord_msg(msg, rdev, wpan_dev, 0, 0, 0,
+					  NL802154_CMD_NEW_COORDINATOR, desc);
+	if (ret < 0) {
+		nlmsg_free(msg);
+		return ret;
+	}
+
+	return genlmsg_multicast_netns(&nl802154_fam, wpan_phy_net(wpan_phy),
+				       msg, 0, NL802154_MCGRP_SCAN, GFP_ATOMIC);
+}
+
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 static const struct nla_policy nl802154_dev_addr_policy[NL802154_DEV_ADDR_ATTR_MAX + 1] = {
 	[NL802154_DEV_ADDR_ATTR_PAN_ID] = { .type = NLA_U16 },
diff --git a/net/ieee802154/nl802154.h b/net/ieee802154/nl802154.h
index 8c4b6d08954c..97600c6ee055 100644
--- a/net/ieee802154/nl802154.h
+++ b/net/ieee802154/nl802154.h
@@ -4,5 +4,8 @@
 
 int nl802154_init(void);
 void nl802154_exit(void);
+int nl802154_advertise_new_coordinator(struct wpan_phy *wpan_phy,
+				       struct wpan_dev *wpan_dev,
+				       struct ieee802154_coord_desc *desc);
 
 #endif /* __IEEE802154_NL802154_H */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 03/20] net: ieee802154: Handle coordinators discovery
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
  2022-07-01 14:30 ` [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces Miquel Raynal
  2022-07-01 14:30 ` [PATCH wpan-next 02/20] net: ieee802154: Advertize coordinators discovery Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-01 14:30 ` [PATCH wpan-next 04/20] net: ieee802154: Trace the registration of new PANs Miquel Raynal
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

Let's introduce helpers for giving the MAC layer a generic interface for
advertising discovered coordinators/PANs upon beacon reception. This
support requires the MAC layers to:
- Allocate a coordinator/PAN descriptor and fill it.
- Register this structure, giving the generic ieee802154 layer the
  necessary information about the coordinator/PAN the beacon originates
  from.
- To flush all the allocated structures once the scan is done.

The generic layer keeps a temporary list of the discovered coordinators
to avoid spamming the user with identical information. So only new
discoveries are forwarded to the user through netlink messages (already
implemented).

Co-developed-by: David Girault <david.girault@qorvo.com>
Signed-off-by: David Girault <david.girault@qorvo.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 include/net/cfg802154.h   |  11 ++++
 net/ieee802154/Makefile   |   2 +-
 net/ieee802154/core.c     |   2 +
 net/ieee802154/nl802154.c |   2 +
 net/ieee802154/pan.c      | 112 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 128 insertions(+), 1 deletion(-)
 create mode 100644 net/ieee802154/pan.c

diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index 1f1b275dcabd..895948b433de 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -398,6 +398,10 @@ struct wpan_dev {
 
 	/* fallback for acknowledgment bit setting */
 	bool ackreq;
+
+	/* Coordinators management during scans */
+	spinlock_t coord_list_lock;
+	struct list_head coord_list;
 };
 
 #define to_phy(_dev)	container_of(_dev, struct wpan_phy, dev)
@@ -446,4 +450,11 @@ static inline const char *wpan_phy_name(struct wpan_phy *phy)
 
 void ieee802154_configure_durations(struct wpan_phy *phy);
 
+struct ieee802154_coord_desc *
+cfg802154_alloc_coordinator(struct ieee802154_addr *coord);
+void cfg802154_record_coordinator(struct wpan_phy *wpan_phy,
+				  struct wpan_dev *wpan_dev,
+				  struct ieee802154_coord_desc *desc);
+void cfg802154_flush_known_coordinators(struct wpan_dev *wpan_dev);
+
 #endif /* __NET_CFG802154_H */
diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile
index f05b7bdae2aa..6b7c66de730d 100644
--- a/net/ieee802154/Makefile
+++ b/net/ieee802154/Makefile
@@ -4,7 +4,7 @@ obj-$(CONFIG_IEEE802154_SOCKET) += ieee802154_socket.o
 obj-y += 6lowpan/
 
 ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o core.o \
-                header_ops.o sysfs.o nl802154.o trace.o
+                header_ops.o sysfs.o nl802154.o pan.o trace.o
 ieee802154_socket-y := socket.o
 
 CFLAGS_trace.o := -I$(src)
diff --git a/net/ieee802154/core.c b/net/ieee802154/core.c
index 57546e07e06a..091eb467fde6 100644
--- a/net/ieee802154/core.c
+++ b/net/ieee802154/core.c
@@ -276,6 +276,8 @@ static int cfg802154_netdev_notifier_call(struct notifier_block *nb,
 		wpan_dev->identifier = ++rdev->wpan_dev_id;
 		list_add_rcu(&wpan_dev->list, &rdev->wpan_dev_list);
 		rdev->devlist_generation++;
+		spin_lock_init(&wpan_dev->coord_list_lock);
+		INIT_LIST_HEAD(&wpan_dev->coord_list);
 
 		wpan_dev->netdev = dev;
 		break;
diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
index 7c0aec10ef7f..8598767c0c0a 100644
--- a/net/ieee802154/nl802154.c
+++ b/net/ieee802154/nl802154.c
@@ -1368,6 +1368,8 @@ int nl802154_advertise_new_coordinator(struct wpan_phy *wpan_phy,
 	struct sk_buff *msg;
 	int ret;
 
+	lockdep_assert(&wpan_dev->coord_list_lock);
+
 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
 	if (!msg)
 		return -ENOMEM;
diff --git a/net/ieee802154/pan.c b/net/ieee802154/pan.c
new file mode 100644
index 000000000000..134a13ff0a87
--- /dev/null
+++ b/net/ieee802154/pan.c
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IEEE 802.15.4 PAN management
+ *
+ * Copyright (C) Qorvo, 2021
+ * Authors:
+ *   - David Girault <david.girault@qorvo.com>
+ *   - Miquel Raynal <miquel.raynal@bootlin.com>
+ */
+
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+
+#include <net/cfg802154.h>
+#include <net/af_ieee802154.h>
+
+#include "ieee802154.h"
+#include "../ieee802154/nl802154.h"
+
+struct ieee802154_coord_desc *
+cfg802154_alloc_coordinator(struct ieee802154_addr *coord)
+{
+	struct ieee802154_coord_desc *desc;
+
+	desc = kzalloc(sizeof(*desc), GFP_ATOMIC);
+	if (!desc)
+		return ERR_PTR(-ENOMEM);
+
+	desc->addr = kzalloc(sizeof(*coord), GFP_ATOMIC);
+	if (!desc->addr) {
+		kfree(desc);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	memcpy(desc->addr, coord, sizeof(*coord));
+
+	return desc;
+}
+EXPORT_SYMBOL_GPL(cfg802154_alloc_coordinator);
+
+static void cfg802154_free_coordinator_desc(struct ieee802154_coord_desc *desc)
+{
+	kfree(desc->addr);
+	kfree(desc);
+}
+
+static bool
+cfg802154_is_same_coordinator(struct ieee802154_coord_desc *a,
+			      struct ieee802154_coord_desc *b)
+{
+	if (a->addr->pan_id != b->addr->pan_id)
+		return false;
+
+	if (a->addr->mode != b->addr->mode)
+		return false;
+
+	if (a->addr->mode == IEEE802154_ADDR_SHORT &&
+	    a->addr->short_addr == b->addr->short_addr)
+		return true;
+	else if (a->addr->mode == IEEE802154_ADDR_LONG &&
+		 a->addr->extended_addr == b->addr->extended_addr)
+		return true;
+
+	return false;
+}
+
+static bool
+cfg802154_coordinator_is_known(struct wpan_dev *wpan_dev,
+			       struct ieee802154_coord_desc *desc)
+{
+	struct ieee802154_coord_desc *item;
+
+	list_for_each_entry(item, &wpan_dev->coord_list, node)
+		if (cfg802154_is_same_coordinator(item, desc))
+			return true;
+
+	return false;
+}
+
+void cfg802154_record_coordinator(struct wpan_phy *wpan_phy,
+				  struct wpan_dev *wpan_dev,
+				  struct ieee802154_coord_desc *desc)
+{
+	spin_lock_bh(&wpan_dev->coord_list_lock);
+
+	if (cfg802154_coordinator_is_known(wpan_dev, desc)) {
+		cfg802154_free_coordinator_desc(desc);
+	} else {
+		list_add_tail(&desc->node, &wpan_dev->coord_list);
+		nl802154_advertise_new_coordinator(wpan_phy, wpan_dev, desc);
+	}
+
+	spin_unlock_bh(&wpan_dev->coord_list_lock);
+}
+EXPORT_SYMBOL_GPL(cfg802154_record_coordinator);
+
+void cfg802154_flush_known_coordinators(struct wpan_dev *wpan_dev)
+{
+	struct ieee802154_coord_desc *desc, *tmp;
+
+	spin_lock_bh(&wpan_dev->coord_list_lock);
+
+	list_for_each_entry_safe(desc, tmp, &wpan_dev->coord_list, node) {
+		list_del(&desc->node);
+		cfg802154_free_coordinator_desc(desc);
+	}
+
+	spin_unlock_bh(&wpan_dev->coord_list_lock);
+}
+EXPORT_SYMBOL_GPL(cfg802154_flush_known_coordinators);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 04/20] net: ieee802154: Trace the registration of new PANs
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
                   ` (2 preceding siblings ...)
  2022-07-01 14:30 ` [PATCH wpan-next 03/20] net: ieee802154: Handle " Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-01 14:30 ` [PATCH wpan-next 05/20] net: ieee802154: Define frame types Miquel Raynal
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

From: David Girault <david.girault@qorvo.com>

Add an internal trace when new PANs get discovered.

Signed-off-by: David Girault <david.girault@qorvo.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 net/ieee802154/pan.c   |  2 ++
 net/ieee802154/trace.h | 25 +++++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/net/ieee802154/pan.c b/net/ieee802154/pan.c
index 134a13ff0a87..79d365fdf7d5 100644
--- a/net/ieee802154/pan.c
+++ b/net/ieee802154/pan.c
@@ -18,6 +18,7 @@
 
 #include "ieee802154.h"
 #include "../ieee802154/nl802154.h"
+#include "trace.h"
 
 struct ieee802154_coord_desc *
 cfg802154_alloc_coordinator(struct ieee802154_addr *coord)
@@ -89,6 +90,7 @@ void cfg802154_record_coordinator(struct wpan_phy *wpan_phy,
 		cfg802154_free_coordinator_desc(desc);
 	} else {
 		list_add_tail(&desc->node, &wpan_dev->coord_list);
+		trace_802154_new_coordinator(desc);
 		nl802154_advertise_new_coordinator(wpan_phy, wpan_dev, desc);
 	}
 
diff --git a/net/ieee802154/trace.h b/net/ieee802154/trace.h
index 19c2e5d60e76..03b3817c34ad 100644
--- a/net/ieee802154/trace.h
+++ b/net/ieee802154/trace.h
@@ -295,6 +295,31 @@ TRACE_EVENT(802154_rdev_set_ackreq_default,
 		WPAN_DEV_PR_ARG, BOOL_TO_STR(__entry->ackreq))
 );
 
+DECLARE_EVENT_CLASS(802154_new_coordinator_evt,
+	TP_PROTO(struct ieee802154_coord_desc *desc),
+	TP_ARGS(desc),
+	TP_STRUCT__entry(
+		__field(__le16, pan_id)
+		__field(__le64, addr)
+		__field(u8, channel)
+		__field(u8, page)
+	),
+	TP_fast_assign(
+		__entry->page = desc->page;
+		__entry->channel = desc->channel;
+		__entry->pan_id = desc->addr->pan_id;
+		__entry->addr = desc->addr->extended_addr;
+	),
+	TP_printk("panid: %u, coord_addr: 0x%llx, page: %u, channel: %u",
+		  __le16_to_cpu(__entry->pan_id), __le64_to_cpu(__entry->addr),
+		  __entry->page, __entry->channel)
+);
+
+DEFINE_EVENT(802154_new_coordinator_evt, 802154_new_coordinator,
+	TP_PROTO(struct ieee802154_coord_desc *desc),
+	TP_ARGS(desc)
+);
+
 TRACE_EVENT(802154_rdev_return_int,
 	TP_PROTO(struct wpan_phy *wpan_phy, int ret),
 	TP_ARGS(wpan_phy, ret),
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 05/20] net: ieee802154: Define frame types
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
                   ` (3 preceding siblings ...)
  2022-07-01 14:30 ` [PATCH wpan-next 04/20] net: ieee802154: Trace the registration of new PANs Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-11  2:06   ` Alexander Aring
  2022-07-01 14:30 ` [PATCH wpan-next 06/20] net: ieee802154: Add support for user scanning requests Miquel Raynal
                   ` (15 subsequent siblings)
  20 siblings, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

A 802.15.4 frame can be of different types, here is a definition
matching the specification. This enumeration will be soon be used when
adding scanning support.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 include/net/ieee802154_netdev.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
index d0d188c3294b..13167851b1c3 100644
--- a/include/net/ieee802154_netdev.h
+++ b/include/net/ieee802154_netdev.h
@@ -69,6 +69,17 @@ struct ieee802154_hdr_fc {
 #endif
 };
 
+enum ieee802154_frame_type {
+	IEEE802154_BEACON_FRAME,
+	IEEE802154_DATA_FRAME,
+	IEEE802154_ACKNOWLEDGEMENT_FRAME,
+	IEEE802154_MAC_COMMAND_FRAME,
+	IEEE802154_RESERVED_FRAME,
+	IEEE802154_MULTIPURPOSE_FRAME,
+	IEEE802154_FRAGMENT_FRAME,
+	IEEE802154_EXTENDED_FRAME,
+};
+
 struct ieee802154_hdr {
 	struct ieee802154_hdr_fc fc;
 	u8 seq;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 06/20] net: ieee802154: Add support for user scanning requests
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
                   ` (4 preceding siblings ...)
  2022-07-01 14:30 ` [PATCH wpan-next 05/20] net: ieee802154: Define frame types Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-01 14:30 ` [PATCH wpan-next 07/20] net: ieee802154: Define a beacon frame header Miquel Raynal
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

The ieee802154 layer should be able to scan a set of channels in order
to look for beacons advertizing PANs. Supporting this involves adding
two user commands: triggering scans and aborting scans. The user should
also be notified when a new beacon is received and also upon scan
termination.

A scan request structure is created to list the requirements and to be
accessed asynchronously when changing channels or receiving beacons.

Mac layers may now implement the ->trigger_scan() and ->abort_scan()
hooks.

Co-developed-by: David Girault <david.girault@qorvo.com>
Signed-off-by: David Girault <david.girault@qorvo.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 include/linux/ieee802154.h |   3 +
 include/net/cfg802154.h    |  25 +++++
 include/net/nl802154.h     |  47 +++++++++
 net/ieee802154/nl802154.c  | 195 +++++++++++++++++++++++++++++++++++++
 net/ieee802154/nl802154.h  |   2 +
 net/ieee802154/rdev-ops.h  |  28 ++++++
 net/ieee802154/trace.h     |  40 ++++++++
 7 files changed, 340 insertions(+)

diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h
index f1f9412b6ac6..929d4e672575 100644
--- a/include/linux/ieee802154.h
+++ b/include/linux/ieee802154.h
@@ -44,6 +44,9 @@
 #define IEEE802154_SHORT_ADDR_LEN	2
 #define IEEE802154_PAN_ID_LEN		2
 
+/* Duration in superframe order */
+#define IEEE802154_MAX_SCAN_DURATION	14
+#define IEEE802154_ACTIVE_SCAN_DURATION	15
 #define IEEE802154_LIFS_PERIOD		40
 #define IEEE802154_SIFS_PERIOD		12
 #define IEEE802154_MAX_SIFS_FRAME_SIZE	18
diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index 895948b433de..d3354899b67c 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -18,6 +18,7 @@
 
 struct wpan_phy;
 struct wpan_phy_cca;
+struct cfg802154_scan_request;
 
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 struct ieee802154_llsec_device_key;
@@ -67,6 +68,10 @@ struct cfg802154_ops {
 				struct wpan_dev *wpan_dev, bool mode);
 	int	(*set_ackreq_default)(struct wpan_phy *wpan_phy,
 				      struct wpan_dev *wpan_dev, bool ackreq);
+	int	(*trigger_scan)(struct wpan_phy *wpan_phy,
+				struct cfg802154_scan_request *request);
+	int	(*abort_scan)(struct wpan_phy *wpan_phy,
+			      struct wpan_dev *wpan_dev);
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 	void	(*get_llsec_table)(struct wpan_phy *wpan_phy,
 				   struct wpan_dev *wpan_dev,
@@ -275,6 +280,26 @@ struct ieee802154_coord_desc {
 	struct list_head node;
 };
 
+/**
+ * struct cfg802154_scan_request - Scan request
+ *
+ * @type: type of scan to be performed
+ * @page: page on which to perform the scan
+ * @channels: channels in te %page to be scanned
+ * @duration: time spent on each channel, calculated with:
+ *            aBaseSuperframeDuration * (2 ^ duration + 1)
+ * @wpan_dev: the wpan device on which to perform the scan
+ * @wpan_phy: the wpan phy on which to perform the scan
+ */
+struct cfg802154_scan_request {
+	enum nl802154_scan_types type;
+	u8 page;
+	u32 channels;
+	u8 duration;
+	struct wpan_dev *wpan_dev;
+	struct wpan_phy *wpan_phy;
+};
+
 struct ieee802154_llsec_key_id {
 	u8 mode;
 	u8 id;
diff --git a/include/net/nl802154.h b/include/net/nl802154.h
index dba05553d106..0e5934494990 100644
--- a/include/net/nl802154.h
+++ b/include/net/nl802154.h
@@ -59,6 +59,9 @@ enum nl802154_commands {
 	NL802154_CMD_SET_WPAN_PHY_NETNS,
 
 	NL802154_CMD_NEW_COORDINATOR,
+	NL802154_CMD_TRIGGER_SCAN,
+	NL802154_CMD_ABORT_SCAN,
+	NL802154_CMD_SCAN_DONE,
 
 	/* add new commands above here */
 
@@ -136,6 +139,10 @@ enum nl802154_attrs {
 	NL802154_ATTR_NETNS_FD,
 
 	NL802154_ATTR_COORDINATOR,
+	NL802154_ATTR_SCAN_TYPE,
+	NL802154_ATTR_SCAN_FLAGS,
+	NL802154_ATTR_SCAN_CHANNELS,
+	NL802154_ATTR_SCAN_DURATION,
 
 	/* add attributes here, update the policy in nl802154.c */
 
@@ -261,6 +268,46 @@ enum nl802154_coord {
 	NL802154_COORD_MAX,
 };
 
+/**
+ * enum nl802154_scan_types - Scan types
+ *
+ * @__NL802154_SCAN_INVALID: scan type number 0 is reserved
+ * @NL802154_SCAN_ED: An ED scan allows a device to obtain a measure of the peak
+ *	energy in each requested channel
+ * @NL802154_SCAN_ACTIVE: Locate any coordinator transmitting Beacon frames using
+ *	a Beacon Request command
+ * @NL802154_SCAN_PASSIVE: Locate any coordinator transmitting Beacon frames
+ * @NL802154_SCAN_ORPHAN: Relocate coordinator following a loss of synchronisation
+ * @NL802154_SCAN_ENHANCED_ACTIVE: Same as Active using Enhanced Beacon Request
+ *	command instead of Beacon Request command
+ * @NL802154_SCAN_RIT_PASSIVE: Passive scan for RIT Data Request command frames
+ *	instead of Beacon frames
+ * @NL802154_SCAN_ATTR_MAX: Maximum SCAN attribute number
+ */
+enum nl802154_scan_types {
+	__NL802154_SCAN_INVALID,
+	NL802154_SCAN_ED,
+	NL802154_SCAN_ACTIVE,
+	NL802154_SCAN_PASSIVE,
+	NL802154_SCAN_ORPHAN,
+	NL802154_SCAN_ENHANCED_ACTIVE,
+	NL802154_SCAN_RIT_PASSIVE,
+
+	/* keep last */
+	NL802154_SCAN_ATTR_MAX,
+};
+
+/**
+ * enum nl802154_scan_flags - Scan request control flags
+ *
+ * @NL802154_SCAN_FLAG_RANDOM_ADDR: use a random MAC address for this scan (ie.
+ *	a different one for every scan iteration). When the flag is set, full
+ *	randomisation is assumed.
+ */
+enum nl802154_scan_flags {
+	NL802154_SCAN_FLAG_RANDOM_ADDR = BIT(0),
+};
+
 /**
  * enum nl802154_cca_modes - cca modes
  *
diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
index 8598767c0c0a..19b97bc9ddeb 100644
--- a/net/ieee802154/nl802154.c
+++ b/net/ieee802154/nl802154.c
@@ -221,6 +221,10 @@ static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = {
 
 	[NL802154_ATTR_COORDINATOR] = { .type = NLA_NESTED },
 
+	[NL802154_ATTR_SCAN_TYPE] = { .type = NLA_U8 },
+	[NL802154_ATTR_SCAN_CHANNELS] = { .type = NLA_U32 },
+	[NL802154_ATTR_SCAN_DURATION] = { .type = NLA_U8 },
+
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 	[NL802154_ATTR_SEC_ENABLED] = { .type = NLA_U8, },
 	[NL802154_ATTR_SEC_OUT_LEVEL] = { .type = NLA_U32, },
@@ -1385,6 +1389,181 @@ int nl802154_advertise_new_coordinator(struct wpan_phy *wpan_phy,
 				       msg, 0, NL802154_MCGRP_SCAN, GFP_ATOMIC);
 }
 
+static int nl802154_trigger_scan(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;
+	struct wpan_phy *wpan_phy = &rdev->wpan_phy;
+	struct cfg802154_scan_request *request;
+	u8 type;
+	int err;
+
+	/* Monitors are not allowed to perform scans */
+	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
+		return -EPERM;
+
+	request = kzalloc(sizeof(*request), GFP_KERNEL);
+	if (!request)
+		return -ENOMEM;
+
+	request->wpan_dev = wpan_dev;
+	request->wpan_phy = wpan_phy;
+
+	type = nla_get_u8(info->attrs[NL802154_ATTR_SCAN_TYPE]);
+	switch (type) {
+	case NL802154_SCAN_PASSIVE:
+		request->type = type;
+		break;
+	default:
+		pr_err("Unsupported scan type: %d\n", type);
+		err = -EINVAL;
+		goto free_request;
+	}
+
+	if (info->attrs[NL802154_ATTR_PAGE]) {
+		request->page = nla_get_u8(info->attrs[NL802154_ATTR_PAGE]);
+		if (request->page > IEEE802154_MAX_PAGE) {
+			pr_err("Invalid page %d > %d\n",
+			       request->page, IEEE802154_MAX_PAGE);
+			err = -EINVAL;
+			goto free_request;
+		}
+	} else {
+		/* Use current page by default */
+		request->page = wpan_phy->current_page;
+	}
+
+	if (info->attrs[NL802154_ATTR_SCAN_CHANNELS]) {
+		request->channels = nla_get_u32(info->attrs[NL802154_ATTR_SCAN_CHANNELS]);
+		if (request->channels >= BIT(IEEE802154_MAX_CHANNEL + 1)) {
+			pr_err("Invalid channels bitfield %x ≥ %lx\n",
+			       request->channels,
+			       BIT(IEEE802154_MAX_CHANNEL + 1));
+			err = -EINVAL;
+			goto free_request;
+		}
+	} else {
+		/* Scan all supported channels by default */
+		request->channels = wpan_phy->supported.channels[request->page];
+	}
+
+	if (info->attrs[NL802154_ATTR_SCAN_DURATION]) {
+		request->duration = nla_get_u8(info->attrs[NL802154_ATTR_SCAN_DURATION]);
+		if (request->duration > IEEE802154_MAX_SCAN_DURATION) {
+			pr_err("Duration is out of range\n");
+			err = -EINVAL;
+			goto free_request;
+		}
+	} else {
+		/* Use maximum duration order by default */
+		request->duration = IEEE802154_MAX_SCAN_DURATION;
+	}
+
+	if (wpan_dev->netdev)
+		dev_hold(wpan_dev->netdev);
+
+	err = rdev_trigger_scan(rdev, request);
+	if (err) {
+		pr_err("Failure starting scanning (%d)\n", err);
+		goto free_device;
+	}
+
+	return 0;
+
+free_device:
+	if (wpan_dev->netdev)
+		dev_put(wpan_dev->netdev);
+free_request:
+	kfree(request);
+
+	return err;
+}
+
+static int nl802154_prep_end_scan_msg(struct sk_buff *msg,
+				      struct cfg802154_registered_device *rdev,
+				      struct wpan_dev *wpan_dev,
+				      u32 portid, u32 seq, int flags, u8 cmd)
+{
+	void *hdr;
+
+	hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
+	if (!hdr)
+		return -ENOBUFS;
+
+	if (nla_put_u32(msg, NL802154_ATTR_WPAN_PHY, rdev->wpan_phy_idx))
+		goto nla_put_failure;
+
+	if (wpan_dev->netdev &&
+	    nla_put_u32(msg, NL802154_ATTR_IFINDEX, wpan_dev->netdev->ifindex))
+		goto nla_put_failure;
+
+	if (nla_put_u64_64bit(msg, NL802154_ATTR_WPAN_DEV,
+			      wpan_dev_id(wpan_dev), NL802154_ATTR_PAD))
+		goto nla_put_failure;
+
+	genlmsg_end(msg, hdr);
+
+	return 0;
+
+nla_put_failure:
+	genlmsg_cancel(msg, hdr);
+
+	return -EMSGSIZE;
+}
+
+static int nl802154_send_scan_done_msg(struct cfg802154_registered_device *rdev,
+				       struct wpan_dev *wpan_dev)
+{
+	struct sk_buff *msg;
+	int ret;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	ret = nl802154_prep_end_scan_msg(msg, rdev, wpan_dev, 0, 0, 0,
+					 NL802154_CMD_SCAN_DONE);
+	if (ret < 0) {
+		nlmsg_free(msg);
+		return ret;
+	}
+
+	return genlmsg_multicast_netns(&nl802154_fam,
+				       wpan_phy_net(&rdev->wpan_phy), msg, 0,
+				       NL802154_MCGRP_SCAN, GFP_KERNEL);
+}
+
+int nl802154_send_scan_done(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
+			    struct cfg802154_scan_request *request)
+{
+	struct cfg802154_registered_device *rdev = wpan_phy_to_rdev(wpan_phy);
+	int err;
+
+	/* Ignore errors when there are no listeners */
+	err = nl802154_send_scan_done_msg(rdev, wpan_dev);
+	if (err == -ESRCH)
+		err = 0;
+
+	kfree(request);
+
+	if (wpan_dev->netdev)
+		dev_put(wpan_dev->netdev);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(nl802154_send_scan_done);
+
+static int nl802154_abort_scan(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;
+
+	/* Resources are released in the notification helper above */
+	return rdev_abort_scan(rdev, wpan_dev);
+}
+
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 static const struct nla_policy nl802154_dev_addr_policy[NL802154_DEV_ADDR_ATTR_MAX + 1] = {
 	[NL802154_DEV_ADDR_ATTR_PAN_ID] = { .type = NLA_U16 },
@@ -2473,6 +2652,22 @@ static const struct genl_ops nl802154_ops[] = {
 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
 				  NL802154_FLAG_NEED_RTNL,
 	},
+	{
+		.cmd = NL802154_CMD_TRIGGER_SCAN,
+		.doit = nl802154_trigger_scan,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL802154_FLAG_NEED_NETDEV |
+				  NL802154_FLAG_CHECK_NETDEV_UP |
+				  NL802154_FLAG_NEED_RTNL,
+	},
+	{
+		.cmd = NL802154_CMD_ABORT_SCAN,
+		.doit = nl802154_abort_scan,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL802154_FLAG_NEED_NETDEV |
+				  NL802154_FLAG_CHECK_NETDEV_UP |
+				  NL802154_FLAG_NEED_RTNL,
+	},
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 	{
 		.cmd = NL802154_CMD_SET_SEC_PARAMS,
diff --git a/net/ieee802154/nl802154.h b/net/ieee802154/nl802154.h
index 97600c6ee055..961e2ac86c8c 100644
--- a/net/ieee802154/nl802154.h
+++ b/net/ieee802154/nl802154.h
@@ -7,5 +7,7 @@ void nl802154_exit(void);
 int nl802154_advertise_new_coordinator(struct wpan_phy *wpan_phy,
 				       struct wpan_dev *wpan_dev,
 				       struct ieee802154_coord_desc *desc);
+int nl802154_send_scan_done(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
+			    struct cfg802154_scan_request *request);
 
 #endif /* __IEEE802154_NL802154_H */
diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h
index 598f5af49775..e171d74c3251 100644
--- a/net/ieee802154/rdev-ops.h
+++ b/net/ieee802154/rdev-ops.h
@@ -209,6 +209,34 @@ rdev_set_ackreq_default(struct cfg802154_registered_device *rdev,
 	return ret;
 }
 
+static inline int rdev_trigger_scan(struct cfg802154_registered_device *rdev,
+				    struct cfg802154_scan_request *request)
+{
+	int ret;
+
+	if (!rdev->ops->trigger_scan)
+		return -EOPNOTSUPP;
+
+	trace_802154_rdev_trigger_scan(&rdev->wpan_phy, request);
+	ret = rdev->ops->trigger_scan(&rdev->wpan_phy, request);
+	trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+	return ret;
+}
+
+static inline int rdev_abort_scan(struct cfg802154_registered_device *rdev,
+				  struct wpan_dev *wpan_dev)
+{
+	int ret;
+
+	if (!rdev->ops->abort_scan)
+		return -EOPNOTSUPP;
+
+	trace_802154_rdev_abort_scan(&rdev->wpan_phy, wpan_dev);
+	ret = rdev->ops->abort_scan(&rdev->wpan_phy, wpan_dev);
+	trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+	return ret;
+}
+
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 /* TODO this is already a nl802154, so move into ieee802154 */
 static inline void
diff --git a/net/ieee802154/trace.h b/net/ieee802154/trace.h
index 03b3817c34ad..d193f66ae0c7 100644
--- a/net/ieee802154/trace.h
+++ b/net/ieee802154/trace.h
@@ -320,6 +320,46 @@ DEFINE_EVENT(802154_new_coordinator_evt, 802154_new_coordinator,
 	TP_ARGS(desc)
 );
 
+TRACE_EVENT(802154_rdev_trigger_scan,
+	TP_PROTO(struct wpan_phy *wpan_phy,
+		 struct cfg802154_scan_request *request),
+	TP_ARGS(wpan_phy, request),
+	TP_STRUCT__entry(
+		WPAN_PHY_ENTRY
+		__field(u8, page)
+		__field(u32, channels)
+		__field(u8, duration)
+	),
+	TP_fast_assign(
+		WPAN_PHY_ASSIGN;
+		__entry->page = request->page;
+		__entry->channels = request->channels;
+		__entry->duration = request->duration;
+	),
+	TP_printk(WPAN_PHY_PR_FMT ", scan, page: %d, channels: %x, duration %d",
+		  WPAN_PHY_PR_ARG, __entry->page, __entry->channels, __entry->duration)
+);
+
+DECLARE_EVENT_CLASS(802154_wdev_template,
+	TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev),
+	TP_ARGS(wpan_phy, wpan_dev),
+	TP_STRUCT__entry(
+		WPAN_PHY_ENTRY
+		WPAN_DEV_ENTRY
+	),
+	TP_fast_assign(
+		WPAN_PHY_ASSIGN;
+		WPAN_DEV_ASSIGN;
+	),
+	TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT,
+		  WPAN_PHY_PR_ARG, WPAN_DEV_PR_ARG)
+);
+
+DEFINE_EVENT(802154_wdev_template, 802154_rdev_abort_scan,
+	TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev),
+	TP_ARGS(wpan_phy, wpan_dev)
+);
+
 TRACE_EVENT(802154_rdev_return_int,
 	TP_PROTO(struct wpan_phy *wpan_phy, int ret),
 	TP_ARGS(wpan_phy, ret),
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 07/20] net: ieee802154: Define a beacon frame header
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
                   ` (5 preceding siblings ...)
  2022-07-01 14:30 ` [PATCH wpan-next 06/20] net: ieee802154: Add support for user scanning requests Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-01 14:30 ` [PATCH wpan-next 08/20] net: mac802154: Prepare forcing specific symbol duration Miquel Raynal
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

This definition will be used when adding support for scanning and defines
the content of a beacon frame header as in the 802.15.4 specification.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 include/net/ieee802154_netdev.h | 36 +++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
index 13167851b1c3..45dff5d11bc8 100644
--- a/include/net/ieee802154_netdev.h
+++ b/include/net/ieee802154_netdev.h
@@ -22,6 +22,42 @@
 
 #include <net/cfg802154.h>
 
+struct ieee802154_beacon_hdr {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+	u16 beacon_order:4,
+	    superframe_order:4,
+	    final_cap_slot:4,
+	    battery_life_ext:1,
+	    reserved0:1,
+	    pan_coordinator:1,
+	    assoc_permit:1;
+	u8  gts_count:3,
+	    gts_reserved:4,
+	    gts_permit:1;
+	u8  pend_short_addr_count:3,
+	    reserved1:1,
+	    pend_ext_addr_count:3,
+	    reserved2:1;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+	u16 assoc_permit:1,
+	    pan_coordinator:1,
+	    reserved0:1,
+	    battery_life_ext:1,
+	    final_cap_slot:4,
+	    superframe_order:4,
+	    beacon_order:4;
+	u8  gts_permit:1,
+	    gts_reserved:4,
+	    gts_count:3;
+	u8  reserved2:1,
+	    pend_ext_addr_count:3,
+	    reserved1:1,
+	    pend_short_addr_count:3;
+#else
+#error	"Please fix <asm/byteorder.h>"
+#endif
+} __packed;
+
 struct ieee802154_sechdr {
 #if defined(__LITTLE_ENDIAN_BITFIELD)
 	u8 level:3,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 08/20] net: mac802154: Prepare forcing specific symbol duration
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
                   ` (6 preceding siblings ...)
  2022-07-01 14:30 ` [PATCH wpan-next 07/20] net: ieee802154: Define a beacon frame header Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-01 14:30 ` [PATCH wpan-next 09/20] net: mac802154: Introduce a global device lock Miquel Raynal
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

The scan logic will bypass the whole ->set_channel() logic from the top
by calling the driver hook to just switch between channels when
required.

We can no longer rely on the "current" page/channel settings to set the
right symbol duration. Let's add these as new parameters to allow
providing the page/channel couple that we want.

There is no functional change.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 include/net/cfg802154.h |  3 ++-
 net/mac802154/cfg.c     |  2 +-
 net/mac802154/main.c    | 20 +++++++++++---------
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index d3354899b67c..f05ce3c45b5d 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -473,7 +473,8 @@ static inline const char *wpan_phy_name(struct wpan_phy *phy)
 	return dev_name(&phy->dev);
 }
 
-void ieee802154_configure_durations(struct wpan_phy *phy);
+void ieee802154_configure_durations(struct wpan_phy *phy,
+				    unsigned int page, unsigned int channel);
 
 struct ieee802154_coord_desc *
 cfg802154_alloc_coordinator(struct ieee802154_addr *coord);
diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c
index 93df24f75572..4116a894c86e 100644
--- a/net/mac802154/cfg.c
+++ b/net/mac802154/cfg.c
@@ -118,7 +118,7 @@ ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel)
 	if (!ret) {
 		wpan_phy->current_page = page;
 		wpan_phy->current_channel = channel;
-		ieee802154_configure_durations(wpan_phy);
+		ieee802154_configure_durations(wpan_phy, page, channel);
 	}
 
 	return ret;
diff --git a/net/mac802154/main.c b/net/mac802154/main.c
index 40fab08df24b..a2da9d4c5273 100644
--- a/net/mac802154/main.c
+++ b/net/mac802154/main.c
@@ -113,32 +113,33 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
 }
 EXPORT_SYMBOL(ieee802154_alloc_hw);
 
-void ieee802154_configure_durations(struct wpan_phy *phy)
+void ieee802154_configure_durations(struct wpan_phy *phy,
+				    unsigned int page, unsigned int channel)
 {
 	u32 duration = 0;
 
-	switch (phy->current_page) {
+	switch (page) {
 	case 0:
-		if (BIT(phy->current_channel) & 0x1)
+		if (BIT(channel) & 0x1)
 			/* 868 MHz BPSK 802.15.4-2003: 20 ksym/s */
 			duration = 50 * NSEC_PER_USEC;
-		else if (BIT(phy->current_channel) & 0x7FE)
+		else if (BIT(channel) & 0x7FE)
 			/* 915 MHz BPSK	802.15.4-2003: 40 ksym/s */
 			duration = 25 * NSEC_PER_USEC;
-		else if (BIT(phy->current_channel) & 0x7FFF800)
+		else if (BIT(channel) & 0x7FFF800)
 			/* 2400 MHz O-QPSK 802.15.4-2006: 62.5 ksym/s */
 			duration = 16 * NSEC_PER_USEC;
 		break;
 	case 2:
-		if (BIT(phy->current_channel) & 0x1)
+		if (BIT(channel) & 0x1)
 			/* 868 MHz O-QPSK 802.15.4-2006: 25 ksym/s */
 			duration = 40 * NSEC_PER_USEC;
-		else if (BIT(phy->current_channel) & 0x7FE)
+		else if (BIT(channel) & 0x7FE)
 			/* 915 MHz O-QPSK 802.15.4-2006: 62.5 ksym/s */
 			duration = 16 * NSEC_PER_USEC;
 		break;
 	case 3:
-		if (BIT(phy->current_channel) & 0x3FFF)
+		if (BIT(channel) & 0x3FFF)
 			/* 2.4 GHz CSS 802.15.4a-2007: 1/6 Msym/s */
 			duration = 6 * NSEC_PER_USEC;
 		break;
@@ -201,7 +202,8 @@ int ieee802154_register_hw(struct ieee802154_hw *hw)
 
 	ieee802154_setup_wpan_phy_pib(local->phy);
 
-	ieee802154_configure_durations(local->phy);
+	ieee802154_configure_durations(local->phy, local->phy->current_page,
+				       local->phy->current_channel);
 
 	if (!(hw->flags & IEEE802154_HW_CSMA_PARAMS)) {
 		local->phy->supported.min_csma_backoffs = 4;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 09/20] net: mac802154: Introduce a global device lock
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
                   ` (7 preceding siblings ...)
  2022-07-01 14:30 ` [PATCH wpan-next 08/20] net: mac802154: Prepare forcing specific symbol duration Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-04  1:12   ` Alexander Aring
  2022-07-01 14:30 ` [PATCH wpan-next 10/20] net: mac802154: Handle passive scanning Miquel Raynal
                   ` (11 subsequent siblings)
  20 siblings, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

The purpose of this device lock is to prevent the removal of the device
while an asynchronous MLME operation happens. The RTNL works well for
that but in a later series having the RTNL taken here will be
problematic and will cause lockdep to warn us about a circular
dependency. We don't really need the RTNL here, just a serialization
over this operation.

Replace the RTNL calls with this new lock.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 net/mac802154/ieee802154_i.h |  2 ++
 net/mac802154/iface.c        |  4 ++++
 net/mac802154/main.c         |  1 +
 net/mac802154/tx.c           | 12 ++++++------
 4 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h
index 010365a6364e..b8775bcc9003 100644
--- a/net/mac802154/ieee802154_i.h
+++ b/net/mac802154/ieee802154_i.h
@@ -29,7 +29,9 @@ struct ieee802154_local {
 	/* ieee802154 phy */
 	struct wpan_phy *phy;
 
+	/* Open/close counter and lock */
 	int open_count;
+	struct mutex device_lock;
 
 	/* As in mac80211 slaves list is modified:
 	 * 1) under the RTNL
diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
index 7ac0c5685d3f..7715e17d9ba1 100644
--- a/net/mac802154/iface.c
+++ b/net/mac802154/iface.c
@@ -315,11 +315,15 @@ static int mac802154_slave_close(struct net_device *dev)
 
 	ASSERT_RTNL();
 
+	mutex_lock(&local->device_lock);
+
 	netif_stop_queue(dev);
 	local->open_count--;
 
 	clear_bit(SDATA_STATE_RUNNING, &sdata->state);
 
+	mutex_unlock(&local->device_lock);
+
 	if (!local->open_count)
 		ieee802154_stop_device(local);
 
diff --git a/net/mac802154/main.c b/net/mac802154/main.c
index a2da9d4c5273..e5fb7ed73663 100644
--- a/net/mac802154/main.c
+++ b/net/mac802154/main.c
@@ -90,6 +90,7 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
 
 	INIT_LIST_HEAD(&local->interfaces);
 	mutex_init(&local->iflist_mtx);
+	mutex_init(&local->device_lock);
 
 	tasklet_setup(&local->tasklet, ieee802154_tasklet_handler);
 
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index 9d8d43cf1e64..fb555797f326 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -143,14 +143,14 @@ int ieee802154_mlme_tx(struct ieee802154_local *local,
 {
 	int ret;
 
-	/* Avoid possible calls to ->ndo_stop() when we asynchronously perform
-	 * MLME transmissions.
+	/* Serialize possible calls to ->ndo_stop() when we asynchronously
+	 * perform MLME transmissions.
 	 */
-	rtnl_lock();
+	mutex_lock(&local->device_lock);
 
 	/* Ensure the device was not stopped, otherwise error out */
 	if (!local->open_count) {
-		rtnl_unlock();
+		mutex_unlock(&local->device_lock);
 		return -ENETDOWN;
 	}
 
@@ -158,14 +158,14 @@ int ieee802154_mlme_tx(struct ieee802154_local *local,
 	 * net interface expects this cannot happen.
 	 */
 	if (WARN_ON_ONCE(!netif_running(sdata->dev))) {
-		rtnl_unlock();
+		mutex_unlock(&local->device_lock);
 		return -ENETDOWN;
 	}
 
 	ieee802154_tx(local, skb);
 	ret = ieee802154_sync_queue(local);
 
-	rtnl_unlock();
+	mutex_unlock(&local->device_lock);
 
 	return ret;
 }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 10/20] net: mac802154: Handle passive scanning
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
                   ` (8 preceding siblings ...)
  2022-07-01 14:30 ` [PATCH wpan-next 09/20] net: mac802154: Introduce a global device lock Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-15  3:33   ` Alexander Aring
  2022-07-01 14:30 ` [PATCH wpan-next 11/20] net: ieee802154: Add support for user beaconing requests Miquel Raynal
                   ` (10 subsequent siblings)
  20 siblings, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

Implement the core hooks in order to provide the softMAC layer support
for passive scans. Scans are requested by the user and can be aborted.

Changing the channels is prohibited during the scan.

As transceivers enter promiscuous mode during scans, they might stop
checking frame validity so we ensure this gets done at mac level.

The implementation uses a workqueue triggered at a certain interval
depending on the symbol duration for the current channel and the
duration order provided.

Received beacons during a passive scan are processed also in a work
queue and forwarded to the upper layer.

Active scanning is not supported yet.

Co-developed-by: David Girault <david.girault@qorvo.com>
Signed-off-by: David Girault <david.girault@qorvo.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 include/linux/ieee802154.h   |   4 +
 include/net/cfg802154.h      |  12 ++
 net/mac802154/Makefile       |   2 +-
 net/mac802154/cfg.c          |  39 ++++++
 net/mac802154/ieee802154_i.h |  29 ++++
 net/mac802154/iface.c        |   6 +
 net/mac802154/main.c         |   4 +
 net/mac802154/rx.c           |  49 ++++++-
 net/mac802154/scan.c         | 264 +++++++++++++++++++++++++++++++++++
 9 files changed, 405 insertions(+), 4 deletions(-)
 create mode 100644 net/mac802154/scan.c

diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h
index 929d4e672575..94bfee22bd0a 100644
--- a/include/linux/ieee802154.h
+++ b/include/linux/ieee802154.h
@@ -47,6 +47,10 @@
 /* Duration in superframe order */
 #define IEEE802154_MAX_SCAN_DURATION	14
 #define IEEE802154_ACTIVE_SCAN_DURATION	15
+/* Superframe duration in slots */
+#define IEEE802154_SUPERFRAME_PERIOD	16
+/* Various periods expressed in symbols */
+#define IEEE802154_SLOT_PERIOD		60
 #define IEEE802154_LIFS_PERIOD		40
 #define IEEE802154_SIFS_PERIOD		12
 #define IEEE802154_MAX_SIFS_FRAME_SIZE	18
diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index f05ce3c45b5d..206283fd4b72 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -300,6 +300,18 @@ struct cfg802154_scan_request {
 	struct wpan_phy *wpan_phy;
 };
 
+/**
+ * struct cfg802154_mac_pkt - MAC packet descriptor (beacon/command)
+ * @node: MAC packets to process list member
+ * @skb: the received sk_buff
+ * @sdata: the interface on which @skb was received
+ */
+struct cfg802154_mac_pkt {
+	struct list_head node;
+	struct sk_buff *skb;
+	struct ieee802154_sub_if_data *sdata;
+};
+
 struct ieee802154_llsec_key_id {
 	u8 mode;
 	u8 id;
diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile
index 4059295fdbf8..43d1347b37ee 100644
--- a/net/mac802154/Makefile
+++ b/net/mac802154/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_MAC802154)	+= mac802154.o
 mac802154-objs		:= main.o rx.o tx.o mac_cmd.o mib.o \
-			   iface.o llsec.o util.o cfg.o trace.o
+			   iface.o llsec.o util.o cfg.o scan.o trace.o
 
 CFLAGS_trace.o := -I$(src)
diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c
index 4116a894c86e..1f532d93d870 100644
--- a/net/mac802154/cfg.c
+++ b/net/mac802154/cfg.c
@@ -114,6 +114,10 @@ ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel)
 	    wpan_phy->current_channel == channel)
 		return 0;
 
+	/* Refuse to change channels during a scanning operation */
+	if (mac802154_is_scanning(local))
+		return -EBUSY;
+
 	ret = drv_set_channel(local, page, channel);
 	if (!ret) {
 		wpan_phy->current_page = page;
@@ -261,6 +265,39 @@ ieee802154_set_ackreq_default(struct wpan_phy *wpan_phy,
 	return 0;
 }
 
+static int mac802154_trigger_scan(struct wpan_phy *wpan_phy,
+				  struct cfg802154_scan_request *request)
+{
+	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
+	struct ieee802154_sub_if_data *sdata;
+	int ret;
+
+	sdata = IEEE802154_WPAN_DEV_TO_SUB_IF(request->wpan_dev);
+
+	ASSERT_RTNL();
+
+	mutex_lock(&local->scan_lock);
+	ret = mac802154_trigger_scan_locked(sdata, request);
+	mutex_unlock(&local->scan_lock);
+
+	return ret;
+}
+
+static int mac802154_abort_scan(struct wpan_phy *wpan_phy,
+				struct wpan_dev *wpan_dev)
+{
+	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
+	int ret;
+
+	ASSERT_RTNL();
+
+	mutex_lock(&local->scan_lock);
+	ret = mac802154_abort_scan_locked(local);
+	mutex_unlock(&local->scan_lock);
+
+	return ret;
+}
+
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 static void
 ieee802154_get_llsec_table(struct wpan_phy *wpan_phy,
@@ -468,6 +505,8 @@ const struct cfg802154_ops mac802154_config_ops = {
 	.set_max_frame_retries = ieee802154_set_max_frame_retries,
 	.set_lbt_mode = ieee802154_set_lbt_mode,
 	.set_ackreq_default = ieee802154_set_ackreq_default,
+	.trigger_scan = mac802154_trigger_scan,
+	.abort_scan = mac802154_abort_scan,
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 	.get_llsec_table = ieee802154_get_llsec_table,
 	.lock_llsec_table = ieee802154_lock_llsec_table,
diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h
index b8775bcc9003..46394e2e0486 100644
--- a/net/mac802154/ieee802154_i.h
+++ b/net/mac802154/ieee802154_i.h
@@ -21,6 +21,10 @@
 
 #include "llsec.h"
 
+enum ieee802154_ongoing {
+	IEEE802154_IS_SCANNING = BIT(0),
+};
+
 /* mac802154 device private data */
 struct ieee802154_local {
 	struct ieee802154_hw hw;
@@ -50,8 +54,19 @@ struct ieee802154_local {
 
 	struct hrtimer ifs_timer;
 
+	/* Scanning */
+	struct mutex scan_lock;
+	int scan_channel_idx;
+	struct cfg802154_scan_request __rcu *scan_req;
+	struct delayed_work scan_work;
+
+	/* Asynchronous tasks */
+	struct list_head rx_beacon_list;
+	struct work_struct rx_beacon_work;
+
 	bool started;
 	bool suspended;
+	unsigned long ongoing;
 
 	struct tasklet_struct tasklet;
 	struct sk_buff_head skb_queue;
@@ -210,6 +225,20 @@ void mac802154_unlock_table(struct net_device *dev);
 
 int mac802154_wpan_update_llsec(struct net_device *dev);
 
+/* PAN management handling */
+void mac802154_scan_worker(struct work_struct *work);
+int mac802154_trigger_scan_locked(struct ieee802154_sub_if_data *sdata,
+				  struct cfg802154_scan_request *request);
+int mac802154_abort_scan_locked(struct ieee802154_local *local);
+int mac802154_process_beacon(struct ieee802154_local *local,
+			     struct sk_buff *skb);
+void mac802154_rx_beacon_worker(struct work_struct *work);
+
+static inline bool mac802154_is_scanning(struct ieee802154_local *local)
+{
+	return test_bit(IEEE802154_IS_SCANNING, &local->ongoing);
+}
+
 /* interface handling */
 int ieee802154_iface_init(void);
 void ieee802154_iface_exit(void);
diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
index 7715e17d9ba1..431cc544dbf2 100644
--- a/net/mac802154/iface.c
+++ b/net/mac802154/iface.c
@@ -315,6 +315,12 @@ static int mac802154_slave_close(struct net_device *dev)
 
 	ASSERT_RTNL();
 
+	if (mac802154_is_scanning(local)) {
+		mutex_lock(&local->scan_lock);
+		mac802154_abort_scan_locked(local);
+		mutex_unlock(&local->scan_lock);
+	}
+
 	mutex_lock(&local->device_lock);
 
 	netif_stop_queue(dev);
diff --git a/net/mac802154/main.c b/net/mac802154/main.c
index e5fb7ed73663..604fbc5b07df 100644
--- a/net/mac802154/main.c
+++ b/net/mac802154/main.c
@@ -89,14 +89,18 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
 	local->ops = ops;
 
 	INIT_LIST_HEAD(&local->interfaces);
+	INIT_LIST_HEAD(&local->rx_beacon_list);
 	mutex_init(&local->iflist_mtx);
 	mutex_init(&local->device_lock);
+	mutex_init(&local->scan_lock);
 
 	tasklet_setup(&local->tasklet, ieee802154_tasklet_handler);
 
 	skb_queue_head_init(&local->skb_queue);
 
 	INIT_WORK(&local->sync_tx_work, ieee802154_xmit_sync_worker);
+	INIT_DELAYED_WORK(&local->scan_work, mac802154_scan_worker);
+	INIT_WORK(&local->rx_beacon_work, mac802154_rx_beacon_worker);
 
 	/* init supported flags with 802.15.4 default ranges */
 	phy->supported.max_minbe = 8;
diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
index 39459d8d787a..0b1cf8c85ee9 100644
--- a/net/mac802154/rx.c
+++ b/net/mac802154/rx.c
@@ -29,11 +29,36 @@ static int ieee802154_deliver_skb(struct sk_buff *skb)
 	return netif_receive_skb(skb);
 }
 
+void mac802154_rx_beacon_worker(struct work_struct *work)
+{
+	struct ieee802154_local *local =
+		container_of(work, struct ieee802154_local, rx_beacon_work);
+	struct cfg802154_mac_pkt *mac_pkt;
+
+	mutex_lock(&local->scan_lock);
+
+	if (list_empty(&local->rx_beacon_list))
+		goto unlock;
+
+	mac_pkt = list_first_entry(&local->rx_beacon_list,
+				   struct cfg802154_mac_pkt, node);
+
+	mac802154_process_beacon(local, mac_pkt->skb);
+
+	list_del(&mac_pkt->node);
+	kfree_skb(mac_pkt->skb);
+	kfree(mac_pkt);
+
+unlock:
+	mutex_unlock(&local->scan_lock);
+}
+
 static int
 ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata,
 		       struct sk_buff *skb, const struct ieee802154_hdr *hdr)
 {
 	struct wpan_dev *wpan_dev = &sdata->wpan_dev;
+	struct cfg802154_mac_pkt *mac_pkt;
 	__le16 span, sshort;
 	int rc;
 
@@ -94,6 +119,18 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata,
 
 	switch (mac_cb(skb)->type) {
 	case IEEE802154_FC_TYPE_BEACON:
+		if (!mac802154_is_scanning(sdata->local))
+			goto fail;
+
+		mac_pkt = kzalloc(sizeof(*mac_pkt), GFP_ATOMIC);
+		if (!mac_pkt)
+			goto fail;
+
+		mac_pkt->skb = skb_get(skb);
+		mac_pkt->sdata = sdata;
+		list_add_tail(&mac_pkt->node, &sdata->local->rx_beacon_list);
+		queue_work(sdata->local->workqueue, &sdata->local->rx_beacon_work);
+		goto success;
 	case IEEE802154_FC_TYPE_ACK:
 	case IEEE802154_FC_TYPE_MAC_CMD:
 		goto fail;
@@ -109,6 +146,10 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata,
 fail:
 	kfree_skb(skb);
 	return NET_RX_DROP;
+
+success:
+	kfree_skb(skb);
+	return NET_RX_SUCCESS;
 }
 
 static void
@@ -268,10 +309,12 @@ void ieee802154_rx(struct ieee802154_local *local, struct sk_buff *skb)
 
 	ieee802154_monitors_rx(local, skb);
 
-	/* Check if transceiver doesn't validate the checksum.
-	 * If not we validate the checksum here.
+	/* Check if the transceiver doesn't validate the checksum, or if the
+	 * check might have been disabled like during a scan. In these cases,
+	 * we validate the checksum here.
 	 */
-	if (local->hw.flags & IEEE802154_HW_RX_DROP_BAD_CKSUM) {
+	if (local->hw.flags & IEEE802154_HW_RX_DROP_BAD_CKSUM ||
+	    mac802154_is_scanning(local)) {
 		crc = crc_ccitt(0, skb->data, skb->len);
 		if (crc) {
 			rcu_read_unlock();
diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c
new file mode 100644
index 000000000000..c74f6c3baa95
--- /dev/null
+++ b/net/mac802154/scan.c
@@ -0,0 +1,264 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * IEEE 802.15.4 scanning management
+ *
+ * Copyright (C) Qorvo, 2021
+ * Authors:
+ *   - David Girault <david.girault@qorvo.com>
+ *   - Miquel Raynal <miquel.raynal@bootlin.com>
+ */
+
+#include <linux/module.h>
+#include <linux/rtnetlink.h>
+#include <net/mac802154.h>
+
+#include "ieee802154_i.h"
+#include "driver-ops.h"
+#include "../ieee802154/nl802154.h"
+
+static bool mac802154_check_promiscuous(struct ieee802154_local *local)
+{
+	struct ieee802154_sub_if_data *sdata;
+	bool promiscuous_on = false;
+
+	/* Check if one subif is already in promiscuous mode. Since the list is
+	 * protected by its own mutex, take it here to ensure no modification
+	 * occurs during the check.
+	 */
+	rcu_read_lock();
+	list_for_each_entry(sdata, &local->interfaces, list) {
+		if (ieee802154_sdata_running(sdata) &&
+		    sdata->wpan_dev.promiscuous_mode) {
+			/* At least one is in promiscuous mode */
+			promiscuous_on = true;
+			break;
+		}
+	}
+	rcu_read_unlock();
+
+	return promiscuous_on;
+}
+
+static int mac802154_set_promiscuous_mode(struct ieee802154_local *local,
+					  bool state)
+{
+	bool promiscuous_on = mac802154_check_promiscuous(local);
+	int ret;
+
+	if ((state && promiscuous_on) || (!state && !promiscuous_on))
+		return 0;
+
+	ret = drv_set_promiscuous_mode(local, state);
+	if (ret)
+		pr_err("Failed to %s promiscuous mode for SW scanning",
+		       state ? "set" : "reset");
+
+	return ret;
+}
+
+static int mac802154_send_scan_done(struct ieee802154_local *local)
+{
+	struct cfg802154_scan_request *scan_req;
+	struct wpan_phy *wpan_phy;
+	struct wpan_dev *wpan_dev;
+
+	scan_req = rcu_dereference_protected(local->scan_req,
+					     lockdep_is_held(&local->scan_lock));
+	wpan_phy = scan_req->wpan_phy;
+	wpan_dev = scan_req->wpan_dev;
+
+	cfg802154_flush_known_coordinators(wpan_dev);
+
+	return nl802154_send_scan_done(wpan_phy, wpan_dev, scan_req);
+}
+
+static int mac802154_end_of_scan(struct ieee802154_local *local)
+{
+	drv_set_channel(local, local->phy->current_page,
+			local->phy->current_channel);
+	ieee802154_configure_durations(local->phy, local->phy->current_page,
+				       local->phy->current_channel);
+	clear_bit(IEEE802154_IS_SCANNING, &local->ongoing);
+	mac802154_set_promiscuous_mode(local, false);
+	ieee802154_mlme_op_post(local);
+	module_put(local->hw.parent->driver->owner);
+
+	return mac802154_send_scan_done(local);
+}
+
+int mac802154_abort_scan_locked(struct ieee802154_local *local)
+{
+	lockdep_assert_held(&local->scan_lock);
+
+	if (!mac802154_is_scanning(local))
+		return -ESRCH;
+
+	cancel_delayed_work(&local->scan_work);
+
+	return mac802154_end_of_scan(local);
+}
+
+static unsigned int mac802154_scan_get_channel_time(u8 duration_order,
+						    u8 symbol_duration)
+{
+	u64 base_super_frame_duration = (u64)symbol_duration *
+		IEEE802154_SUPERFRAME_PERIOD * IEEE802154_SLOT_PERIOD;
+
+	return usecs_to_jiffies(base_super_frame_duration *
+				(BIT(duration_order) + 1));
+}
+
+void mac802154_flush_queued_beacons(struct ieee802154_local *local)
+{
+	struct cfg802154_mac_pkt *beacon, *tmp;
+
+	lockdep_assert_held(&local->scan_lock);
+
+	list_for_each_entry_safe(beacon, tmp, &local->rx_beacon_list, node) {
+		list_del(&beacon->node);
+		kfree_skb(beacon->skb);
+		kfree(beacon);
+	}
+}
+
+void mac802154_scan_worker(struct work_struct *work)
+{
+	struct ieee802154_local *local =
+		container_of(work, struct ieee802154_local, scan_work.work);
+	struct cfg802154_scan_request *scan_req;
+	struct ieee802154_sub_if_data *sdata;
+	unsigned int scan_duration;
+	unsigned long chan;
+	int ret;
+
+	mutex_lock(&local->scan_lock);
+
+	if (!mac802154_is_scanning(local))
+		goto unlock_mutex;
+
+	scan_req = rcu_dereference_protected(local->scan_req,
+					     lockdep_is_held(&local->scan_lock));
+	sdata = IEEE802154_WPAN_DEV_TO_SUB_IF(scan_req->wpan_dev);
+
+	if (local->suspended || !ieee802154_sdata_running(sdata))
+		goto queue_work;
+
+	do {
+		chan = find_next_bit((const unsigned long *)&scan_req->channels,
+				     IEEE802154_MAX_CHANNEL + 1,
+				     local->scan_channel_idx + 1);
+
+		/* If there are no more channels left, complete the scan */
+		if (chan > IEEE802154_MAX_CHANNEL) {
+			mac802154_end_of_scan(local);
+			goto unlock_mutex;
+		}
+
+		/* Bypass the stack on purpose. As the channel change cannot be
+		 * made atomic with regard to the incoming beacon flow, we flush
+		 * the beacons list after changing the channel and before
+		 * releasing the scan lock, to avoid processing beacons which
+		 * have been received during this time frame.
+		 */
+		ret = drv_set_channel(local, scan_req->page, chan);
+		local->scan_channel_idx = chan;
+		ieee802154_configure_durations(local->phy, scan_req->page, chan);
+		mac802154_flush_queued_beacons(local);
+	} while (ret);
+
+queue_work:
+	scan_duration = mac802154_scan_get_channel_time(scan_req->duration,
+							local->phy->symbol_duration);
+	pr_debug("Scan channel %lu of page %u for %ums\n",
+		 chan, scan_req->page, jiffies_to_msecs(scan_duration));
+	queue_delayed_work(local->workqueue, &local->scan_work, scan_duration);
+
+unlock_mutex:
+	mutex_unlock(&local->scan_lock);
+}
+
+int mac802154_trigger_scan_locked(struct ieee802154_sub_if_data *sdata,
+				  struct cfg802154_scan_request *request)
+{
+	struct ieee802154_local *local = sdata->local;
+	int ret;
+
+	lockdep_assert_held(&local->scan_lock);
+
+	if (mac802154_is_scanning(local))
+		return -EBUSY;
+
+	/* TODO: support other scanning type */
+	if (request->type != NL802154_SCAN_PASSIVE)
+		return -EOPNOTSUPP;
+
+	/* Store scanning parameters */
+	rcu_assign_pointer(local->scan_req, request);
+
+	/* Software scanning requires to set promiscuous mode, so we need to
+	 * pause the Tx queue during the entire operation.
+	 */
+	ieee802154_mlme_op_pre(local);
+
+	ret = mac802154_set_promiscuous_mode(local, true);
+	if (ret)
+		goto cancel_mlme;
+
+	local->scan_channel_idx = -1;
+	set_bit(IEEE802154_IS_SCANNING, &local->ongoing);
+
+	/* Starting a background job, ensure the module cannot be removed */
+	if (!try_module_get(local->hw.parent->driver->owner)) {
+		ret = -ENODEV;
+		goto cancel_promiscuous_mode;
+	}
+
+	queue_delayed_work(local->workqueue, &local->scan_work, 0);
+
+	return 0;
+
+cancel_promiscuous_mode:
+	clear_bit(IEEE802154_IS_SCANNING, &local->ongoing);
+	mac802154_set_promiscuous_mode(local, false);
+cancel_mlme:
+	ieee802154_mlme_op_post(local);
+	return ret;
+}
+
+int mac802154_process_beacon(struct ieee802154_local *local,
+			     struct sk_buff *skb)
+{
+	struct ieee802154_beacon_hdr *bh = (void *)skb->data;
+	struct ieee802154_addr *src = &mac_cb(skb)->source;
+	struct cfg802154_scan_request *scan_req;
+	struct ieee802154_coord_desc *desc;
+
+	/* Check the validity of the frame length */
+	if (skb->len < sizeof(*bh))
+		return -EINVAL;
+
+	if (unlikely(src->mode == IEEE802154_ADDR_NONE))
+		return -EINVAL;
+
+	scan_req = rcu_dereference_protected(local->scan_req,
+					     &local->scan_lock);
+	if (unlikely(!scan_req))
+		return -EINVAL;
+
+	pr_debug("Beacon received on channel %d of page %d\n",
+		 local->scan_channel_idx, scan_req->page);
+
+	/* Parse beacon, create PAN information and forward to upper layers */
+	desc = cfg802154_alloc_coordinator(src);
+	if (!desc)
+		return -ENOMEM;
+
+	desc->page = scan_req->page;
+	desc->channel = local->scan_channel_idx;
+	desc->link_quality = mac_cb(skb)->lqi;
+	desc->superframe_spec = get_unaligned_le16(skb->data);
+	desc->gts_permit = bh->gts_permit;
+	cfg802154_record_coordinator(scan_req->wpan_phy, scan_req->wpan_dev, desc);
+
+	return 0;
+}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 11/20] net: ieee802154: Add support for user beaconing requests
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
                   ` (9 preceding siblings ...)
  2022-07-01 14:30 ` [PATCH wpan-next 10/20] net: mac802154: Handle passive scanning Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-01 14:30 ` [PATCH wpan-next 12/20] net: mac802154: Handle basic beaconing Miquel Raynal
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

Parse user requests for sending beacons, start sending beacons at a
regular pace. If needed, the pace can be updated with a new request. The
process can also be interrupted at any moment.

The page and channel must be changed beforehands if needed. Interval
orders above 14 are reserved to tell a device it must answer BEACON_REQ
coming from another device as part of an active scan procedure and this
is not yet supported.

A netlink "beacon request" structure is created to list the
requirements.

Mac layers may now implement the ->send_beacons() and
->stop_beacons() hooks.

Co-developed-by: David Girault <david.girault@qorvo.com>
Signed-off-by: David Girault <david.girault@qorvo.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 include/net/cfg802154.h   | 23 ++++++++++
 include/net/nl802154.h    |  3 ++
 net/ieee802154/nl802154.c | 96 +++++++++++++++++++++++++++++++++++++++
 net/ieee802154/nl802154.h |  2 +
 net/ieee802154/rdev-ops.h | 28 ++++++++++++
 net/ieee802154/trace.h    | 21 +++++++++
 6 files changed, 173 insertions(+)

diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index 206283fd4b72..d6ff60d900a9 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -19,6 +19,7 @@
 struct wpan_phy;
 struct wpan_phy_cca;
 struct cfg802154_scan_request;
+struct cfg802154_beacon_request;
 
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 struct ieee802154_llsec_device_key;
@@ -72,6 +73,10 @@ struct cfg802154_ops {
 				struct cfg802154_scan_request *request);
 	int	(*abort_scan)(struct wpan_phy *wpan_phy,
 			      struct wpan_dev *wpan_dev);
+	int	(*send_beacons)(struct wpan_phy *wpan_phy,
+				struct cfg802154_beacon_request *request);
+	int	(*stop_beacons)(struct wpan_phy *wpan_phy,
+				struct wpan_dev *wpan_dev);
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 	void	(*get_llsec_table)(struct wpan_phy *wpan_phy,
 				   struct wpan_dev *wpan_dev,
@@ -300,6 +305,24 @@ struct cfg802154_scan_request {
 	struct wpan_phy *wpan_phy;
 };
 
+/**
+ * struct cfg802154_beacon_request - Beacon request descriptor
+ *
+ * @interval: interval n between sendings, in multiple order of the super frame
+ *            duration: aBaseSuperframeDuration * (2^n) unless the interval
+ *            order is greater or equal to 15, in this case beacons won't be
+ *            passively sent out at a fixed rate but instead inform the device
+ *            that it should answer beacon requests as part of active scan
+ *            procedures
+ * @wpan_dev: the concerned wpan device
+ * @wpan_phy: the wpan phy this was for
+ */
+struct cfg802154_beacon_request {
+	u8 interval;
+	struct wpan_dev *wpan_dev;
+	struct wpan_phy *wpan_phy;
+};
+
 /**
  * struct cfg802154_mac_pkt - MAC packet descriptor (beacon/command)
  * @node: MAC packets to process list member
diff --git a/include/net/nl802154.h b/include/net/nl802154.h
index 0e5934494990..244852bc65e0 100644
--- a/include/net/nl802154.h
+++ b/include/net/nl802154.h
@@ -62,6 +62,8 @@ enum nl802154_commands {
 	NL802154_CMD_TRIGGER_SCAN,
 	NL802154_CMD_ABORT_SCAN,
 	NL802154_CMD_SCAN_DONE,
+	NL802154_CMD_SEND_BEACONS,
+	NL802154_CMD_STOP_BEACONS,
 
 	/* add new commands above here */
 
@@ -143,6 +145,7 @@ enum nl802154_attrs {
 	NL802154_ATTR_SCAN_FLAGS,
 	NL802154_ATTR_SCAN_CHANNELS,
 	NL802154_ATTR_SCAN_DURATION,
+	NL802154_ATTR_BEACON_INTERVAL,
 
 	/* add attributes here, update the policy in nl802154.c */
 
diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
index 19b97bc9ddeb..ff8069415e67 100644
--- a/net/ieee802154/nl802154.c
+++ b/net/ieee802154/nl802154.c
@@ -224,6 +224,7 @@ static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = {
 	[NL802154_ATTR_SCAN_TYPE] = { .type = NLA_U8 },
 	[NL802154_ATTR_SCAN_CHANNELS] = { .type = NLA_U32 },
 	[NL802154_ATTR_SCAN_DURATION] = { .type = NLA_U8 },
+	[NL802154_ATTR_BEACON_INTERVAL] = { .type = NLA_U8 },
 
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 	[NL802154_ATTR_SEC_ENABLED] = { .type = NLA_U8, },
@@ -1564,6 +1565,85 @@ static int nl802154_abort_scan(struct sk_buff *skb, struct genl_info *info)
 	return rdev_abort_scan(rdev, wpan_dev);
 }
 
+static int
+nl802154_send_beacons(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;
+	struct wpan_phy *wpan_phy = &rdev->wpan_phy;
+	struct cfg802154_beacon_request *request;
+	int err;
+
+	/* Only coordinators can send beacons */
+	if (wpan_dev->iftype != NL802154_IFTYPE_COORD)
+		return -EOPNOTSUPP;
+
+	if (wpan_dev->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST)) {
+		pr_err("Device is not part of any PAN\n");
+		return -EPERM;
+	}
+
+	request = kzalloc(sizeof(*request), GFP_KERNEL);
+	if (!request)
+		return -ENOMEM;
+
+	request->wpan_dev = wpan_dev;
+	request->wpan_phy = wpan_phy;
+
+	if (info->attrs[NL802154_ATTR_BEACON_INTERVAL]) {
+		request->interval = nla_get_u8(info->attrs[NL802154_ATTR_BEACON_INTERVAL]);
+		if (request->interval > IEEE802154_MAX_SCAN_DURATION) {
+			pr_err("Interval is out of range\n");
+			err = -EINVAL;
+			goto free_request;
+		}
+	} else {
+		/* Use maximum duration order by default */
+		request->interval = IEEE802154_MAX_SCAN_DURATION;
+	}
+
+	if (wpan_dev->netdev)
+		dev_hold(wpan_dev->netdev);
+
+	err = rdev_send_beacons(rdev, request);
+	if (err) {
+		pr_err("Failure starting sending beacons (%d)\n", err);
+		goto free_device;
+	}
+
+	return 0;
+
+free_device:
+	if (wpan_dev->netdev)
+		dev_put(wpan_dev->netdev);
+free_request:
+	kfree(request);
+
+	return err;
+}
+
+void nl802154_end_beaconing(struct wpan_dev *wpan_dev,
+			    struct cfg802154_beacon_request *request)
+{
+	kfree(request);
+
+	if (wpan_dev->netdev)
+		dev_put(wpan_dev->netdev);
+}
+EXPORT_SYMBOL_GPL(nl802154_end_beaconing);
+
+static int
+nl802154_stop_beacons(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;
+
+	/* Resources are released in the notification helper above */
+	return rdev_stop_beacons(rdev, wpan_dev);
+}
+
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 static const struct nla_policy nl802154_dev_addr_policy[NL802154_DEV_ADDR_ATTR_MAX + 1] = {
 	[NL802154_DEV_ADDR_ATTR_PAN_ID] = { .type = NLA_U16 },
@@ -2668,6 +2748,22 @@ static const struct genl_ops nl802154_ops[] = {
 				  NL802154_FLAG_CHECK_NETDEV_UP |
 				  NL802154_FLAG_NEED_RTNL,
 	},
+	{
+		.cmd = NL802154_CMD_SEND_BEACONS,
+		.doit = nl802154_send_beacons,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL802154_FLAG_NEED_NETDEV |
+				  NL802154_FLAG_CHECK_NETDEV_UP |
+				  NL802154_FLAG_NEED_RTNL,
+	},
+	{
+		.cmd = NL802154_CMD_STOP_BEACONS,
+		.doit = nl802154_stop_beacons,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL802154_FLAG_NEED_NETDEV |
+				  NL802154_FLAG_CHECK_NETDEV_UP |
+				  NL802154_FLAG_NEED_RTNL,
+	},
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 	{
 		.cmd = NL802154_CMD_SET_SEC_PARAMS,
diff --git a/net/ieee802154/nl802154.h b/net/ieee802154/nl802154.h
index 961e2ac86c8c..5ae96fe89138 100644
--- a/net/ieee802154/nl802154.h
+++ b/net/ieee802154/nl802154.h
@@ -9,5 +9,7 @@ int nl802154_advertise_new_coordinator(struct wpan_phy *wpan_phy,
 				       struct ieee802154_coord_desc *desc);
 int nl802154_send_scan_done(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 			    struct cfg802154_scan_request *request);
+void nl802154_end_beaconing(struct wpan_dev *wpan_dev,
+			    struct cfg802154_beacon_request *request);
 
 #endif /* __IEEE802154_NL802154_H */
diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h
index e171d74c3251..5eaae15c610e 100644
--- a/net/ieee802154/rdev-ops.h
+++ b/net/ieee802154/rdev-ops.h
@@ -237,6 +237,34 @@ static inline int rdev_abort_scan(struct cfg802154_registered_device *rdev,
 	return ret;
 }
 
+static inline int rdev_send_beacons(struct cfg802154_registered_device *rdev,
+				    struct cfg802154_beacon_request *request)
+{
+	int ret;
+
+	if (!rdev->ops->send_beacons)
+		return -EOPNOTSUPP;
+
+	trace_802154_rdev_send_beacons(&rdev->wpan_phy, request);
+	ret = rdev->ops->send_beacons(&rdev->wpan_phy, request);
+	trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+	return ret;
+}
+
+static inline int rdev_stop_beacons(struct cfg802154_registered_device *rdev,
+				    struct wpan_dev *wpan_dev)
+{
+	int ret;
+
+	if (!rdev->ops->stop_beacons)
+		return -EOPNOTSUPP;
+
+	trace_802154_rdev_stop_beacons(&rdev->wpan_phy, wpan_dev);
+	ret = rdev->ops->stop_beacons(&rdev->wpan_phy, wpan_dev);
+	trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+	return ret;
+}
+
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 /* TODO this is already a nl802154, so move into ieee802154 */
 static inline void
diff --git a/net/ieee802154/trace.h b/net/ieee802154/trace.h
index d193f66ae0c7..68a1f6e66a93 100644
--- a/net/ieee802154/trace.h
+++ b/net/ieee802154/trace.h
@@ -340,6 +340,22 @@ TRACE_EVENT(802154_rdev_trigger_scan,
 		  WPAN_PHY_PR_ARG, __entry->page, __entry->channels, __entry->duration)
 );
 
+TRACE_EVENT(802154_rdev_send_beacons,
+	TP_PROTO(struct wpan_phy *wpan_phy,
+		 struct cfg802154_beacon_request *request),
+	TP_ARGS(wpan_phy, request),
+	TP_STRUCT__entry(
+		WPAN_PHY_ENTRY
+		__field(u8, interval)
+	),
+	TP_fast_assign(
+		WPAN_PHY_ASSIGN;
+		__entry->interval = request->interval;
+	),
+	TP_printk(WPAN_PHY_PR_FMT ", sending beacons (interval order: %d)",
+		  WPAN_PHY_PR_ARG, __entry->interval)
+);
+
 DECLARE_EVENT_CLASS(802154_wdev_template,
 	TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev),
 	TP_ARGS(wpan_phy, wpan_dev),
@@ -360,6 +376,11 @@ DEFINE_EVENT(802154_wdev_template, 802154_rdev_abort_scan,
 	TP_ARGS(wpan_phy, wpan_dev)
 );
 
+DEFINE_EVENT(802154_wdev_template, 802154_rdev_stop_beacons,
+	TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev),
+	TP_ARGS(wpan_phy, wpan_dev)
+);
+
 TRACE_EVENT(802154_rdev_return_int,
 	TP_PROTO(struct wpan_phy *wpan_phy, int ret),
 	TP_ARGS(wpan_phy, ret),
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 12/20] net: mac802154: Handle basic beaconing
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
                   ` (10 preceding siblings ...)
  2022-07-01 14:30 ` [PATCH wpan-next 11/20] net: ieee802154: Add support for user beaconing requests Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-01 14:30 ` [PATCH wpan-next 13/20] net: ieee802154: Add support for user active scan requests Miquel Raynal
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

Implement the core hooks in order to provide the softMAC layer support
for sending beacons. Coordinators may be requested to send beacons in a
beacon enabled PAN in order for the other devices around to self
discover the available PANs automatically.

Changing the channels is prohibited while a beacon operation is
ongoing.

The implementation uses a workqueue triggered at a certain interval
depending on the symbol duration for the current channel and the
interval order provided.

Sending beacons in response to a BEACON_REQ frame (ie. answering active
scans) is not yet supported.

Co-developed-by: David Girault <david.girault@qorvo.com>
Signed-off-by: David Girault <david.girault@qorvo.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 include/net/ieee802154_netdev.h |  24 ++++++
 net/ieee802154/header_ops.c     |  29 +++++++
 net/mac802154/cfg.c             |  39 ++++++++-
 net/mac802154/ieee802154_i.h    |  18 ++++
 net/mac802154/iface.c           |   6 ++
 net/mac802154/main.c            |   2 +
 net/mac802154/scan.c            | 142 ++++++++++++++++++++++++++++++++
 7 files changed, 258 insertions(+), 2 deletions(-)

diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
index 45dff5d11bc8..f7716aeec93b 100644
--- a/include/net/ieee802154_netdev.h
+++ b/include/net/ieee802154_netdev.h
@@ -116,6 +116,21 @@ enum ieee802154_frame_type {
 	IEEE802154_EXTENDED_FRAME,
 };
 
+enum ieee802154_frame_version {
+	IEEE802154_2003_STD,
+	IEEE802154_2006_STD,
+	IEEE802154_STD,
+	IEEE802154_RESERVED_STD,
+	IEEE802154_MULTIPURPOSE_STD = IEEE802154_2003_STD,
+};
+
+enum ieee802154_addressing_mode {
+	IEEE802154_NO_ADDRESSING,
+	IEEE802154_RESERVED,
+	IEEE802154_SHORT_ADDRESSING,
+	IEEE802154_EXTENDED_ADDRESSING,
+};
+
 struct ieee802154_hdr {
 	struct ieee802154_hdr_fc fc;
 	u8 seq;
@@ -124,6 +139,11 @@ struct ieee802154_hdr {
 	struct ieee802154_sechdr sec;
 };
 
+struct ieee802154_beacon_frame {
+	struct ieee802154_hdr mhr;
+	struct ieee802154_beacon_hdr mac_pl;
+};
+
 /* pushes hdr onto the skb. fields of hdr->fc that can be calculated from
  * the contents of hdr will be, and the actual value of those bits in
  * hdr->fc will be ignored. this includes the INTRA_PAN bit and the frame
@@ -149,6 +169,10 @@ int ieee802154_hdr_peek_addrs(const struct sk_buff *skb,
  */
 int ieee802154_hdr_peek(const struct sk_buff *skb, struct ieee802154_hdr *hdr);
 
+/* pushes a beacon frame into an skb */
+int ieee802154_beacon_push(struct sk_buff *skb,
+			   struct ieee802154_beacon_frame *beacon);
+
 int ieee802154_max_payload(const struct ieee802154_hdr *hdr);
 
 static inline int
diff --git a/net/ieee802154/header_ops.c b/net/ieee802154/header_ops.c
index af337cf62764..bab710aa36f9 100644
--- a/net/ieee802154/header_ops.c
+++ b/net/ieee802154/header_ops.c
@@ -6,6 +6,7 @@
  * Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de>
  */
 
+#include <linux/crc-ccitt.h>
 #include <linux/ieee802154.h>
 
 #include <net/mac802154.h>
@@ -120,6 +121,34 @@ ieee802154_hdr_push(struct sk_buff *skb, struct ieee802154_hdr *hdr)
 }
 EXPORT_SYMBOL_GPL(ieee802154_hdr_push);
 
+int ieee802154_beacon_push(struct sk_buff *skb,
+			   struct ieee802154_beacon_frame *beacon)
+{
+	struct ieee802154_beacon_hdr *mac_pl = &beacon->mac_pl;
+	struct ieee802154_hdr *mhr = &beacon->mhr;
+	u16 crc;
+	int ret;
+
+	skb_reserve(skb, sizeof(*mhr));
+	ret = ieee802154_hdr_push(skb, mhr);
+	if (ret < 0)
+		return ret;
+
+	skb_reset_mac_header(skb);
+	skb->mac_len = ret;
+
+	skb_put_data(skb, mac_pl, sizeof(*mac_pl));
+
+	if (mac_pl->pend_short_addr_count || mac_pl->pend_ext_addr_count)
+		return -EOPNOTSUPP;
+
+	crc = crc_ccitt(0, skb->data, skb->len);
+	put_unaligned_le16(crc, skb_put(skb, 2));
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ieee802154_beacon_push);
+
 static int
 ieee802154_hdr_get_addr(const u8 *buf, int mode, bool omit_pan,
 			struct ieee802154_addr *addr)
diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c
index 1f532d93d870..fed9ad38cbce 100644
--- a/net/mac802154/cfg.c
+++ b/net/mac802154/cfg.c
@@ -114,8 +114,8 @@ ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel)
 	    wpan_phy->current_channel == channel)
 		return 0;
 
-	/* Refuse to change channels during a scanning operation */
-	if (mac802154_is_scanning(local))
+	/* Refuse to change channels during scanning or beaconing */
+	if (mac802154_is_scanning(local) || mac802154_is_beaconing(local))
 		return -EBUSY;
 
 	ret = drv_set_channel(local, page, channel);
@@ -298,6 +298,39 @@ static int mac802154_abort_scan(struct wpan_phy *wpan_phy,
 	return ret;
 }
 
+static int mac802154_send_beacons(struct wpan_phy *wpan_phy,
+				  struct cfg802154_beacon_request *request)
+{
+	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
+	struct ieee802154_sub_if_data *sdata;
+	int ret;
+
+	sdata = IEEE802154_WPAN_DEV_TO_SUB_IF(request->wpan_dev);
+
+	ASSERT_RTNL();
+
+	mutex_lock(&local->beacon_lock);
+	ret = mac802154_send_beacons_locked(sdata, request);
+	mutex_unlock(&local->beacon_lock);
+
+	return ret;
+}
+
+static int mac802154_stop_beacons(struct wpan_phy *wpan_phy,
+				  struct wpan_dev *wpan_dev)
+{
+	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
+	int ret;
+
+	ASSERT_RTNL();
+
+	mutex_lock(&local->beacon_lock);
+	ret = mac802154_stop_beacons_locked(local);
+	mutex_unlock(&local->beacon_lock);
+
+	return ret;
+}
+
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 static void
 ieee802154_get_llsec_table(struct wpan_phy *wpan_phy,
@@ -507,6 +540,8 @@ const struct cfg802154_ops mac802154_config_ops = {
 	.set_ackreq_default = ieee802154_set_ackreq_default,
 	.trigger_scan = mac802154_trigger_scan,
 	.abort_scan = mac802154_abort_scan,
+	.send_beacons = mac802154_send_beacons,
+	.stop_beacons = mac802154_stop_beacons,
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 	.get_llsec_table = ieee802154_get_llsec_table,
 	.lock_llsec_table = ieee802154_lock_llsec_table,
diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h
index 46394e2e0486..f70848b60469 100644
--- a/net/mac802154/ieee802154_i.h
+++ b/net/mac802154/ieee802154_i.h
@@ -23,6 +23,7 @@
 
 enum ieee802154_ongoing {
 	IEEE802154_IS_SCANNING = BIT(0),
+	IEEE802154_IS_BEACONING = BIT(1),
 };
 
 /* mac802154 device private data */
@@ -60,6 +61,13 @@ struct ieee802154_local {
 	struct cfg802154_scan_request __rcu *scan_req;
 	struct delayed_work scan_work;
 
+	/* Beaconing */
+	struct mutex beacon_lock;
+	unsigned int beacon_interval;
+	struct ieee802154_beacon_frame beacon;
+	struct cfg802154_beacon_request __rcu *beacon_req;
+	struct delayed_work beacon_work;
+
 	/* Asynchronous tasks */
 	struct list_head rx_beacon_list;
 	struct work_struct rx_beacon_work;
@@ -239,6 +247,16 @@ static inline bool mac802154_is_scanning(struct ieee802154_local *local)
 	return test_bit(IEEE802154_IS_SCANNING, &local->ongoing);
 }
 
+void mac802154_beacon_worker(struct work_struct *work);
+int mac802154_send_beacons_locked(struct ieee802154_sub_if_data *sdata,
+				  struct cfg802154_beacon_request *request);
+int mac802154_stop_beacons_locked(struct ieee802154_local *local);
+
+static inline bool mac802154_is_beaconing(struct ieee802154_local *local)
+{
+	return test_bit(IEEE802154_IS_BEACONING, &local->ongoing);
+}
+
 /* interface handling */
 int ieee802154_iface_init(void);
 void ieee802154_iface_exit(void);
diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
index 431cc544dbf2..54719d3d19c1 100644
--- a/net/mac802154/iface.c
+++ b/net/mac802154/iface.c
@@ -321,6 +321,12 @@ static int mac802154_slave_close(struct net_device *dev)
 		mutex_unlock(&local->scan_lock);
 	}
 
+	if (mac802154_is_beaconing(local)) {
+		mutex_lock(&local->beacon_lock);
+		mac802154_stop_beacons_locked(local);
+		mutex_unlock(&local->beacon_lock);
+	}
+
 	mutex_lock(&local->device_lock);
 
 	netif_stop_queue(dev);
diff --git a/net/mac802154/main.c b/net/mac802154/main.c
index 604fbc5b07df..826a0d2ce395 100644
--- a/net/mac802154/main.c
+++ b/net/mac802154/main.c
@@ -93,6 +93,7 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
 	mutex_init(&local->iflist_mtx);
 	mutex_init(&local->device_lock);
 	mutex_init(&local->scan_lock);
+	mutex_init(&local->beacon_lock);
 
 	tasklet_setup(&local->tasklet, ieee802154_tasklet_handler);
 
@@ -101,6 +102,7 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
 	INIT_WORK(&local->sync_tx_work, ieee802154_xmit_sync_worker);
 	INIT_DELAYED_WORK(&local->scan_work, mac802154_scan_worker);
 	INIT_WORK(&local->rx_beacon_work, mac802154_rx_beacon_worker);
+	INIT_DELAYED_WORK(&local->beacon_work, mac802154_beacon_worker);
 
 	/* init supported flags with 802.15.4 default ranges */
 	phy->supported.max_minbe = 8;
diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c
index c74f6c3baa95..3dd11ec86d06 100644
--- a/net/mac802154/scan.c
+++ b/net/mac802154/scan.c
@@ -16,6 +16,13 @@
 #include "driver-ops.h"
 #include "../ieee802154/nl802154.h"
 
+#define IEEE802154_BEACON_MHR_SZ 13
+#define IEEE802154_BEACON_PL_SZ 4
+#define IEEE802154_CRC_SZ 2
+#define IEEE802154_BEACON_SKB_SZ (IEEE802154_BEACON_MHR_SZ + \
+				  IEEE802154_BEACON_PL_SZ + \
+				  IEEE802154_CRC_SZ)
+
 static bool mac802154_check_promiscuous(struct ieee802154_local *local)
 {
 	struct ieee802154_sub_if_data *sdata;
@@ -262,3 +269,138 @@ int mac802154_process_beacon(struct ieee802154_local *local,
 
 	return 0;
 }
+
+static int mac802154_transmit_beacon_locked(struct ieee802154_local *local,
+					    struct wpan_dev *wpan_dev)
+{
+	struct cfg802154_beacon_request *beacon_req;
+	struct ieee802154_sub_if_data *sdata;
+	struct sk_buff *skb;
+	int ret;
+
+	lockdep_assert_held(&local->beacon_lock);
+
+	/* Update the sequence number */
+	local->beacon.mhr.seq = atomic_inc_return(&wpan_dev->bsn);
+
+	skb = alloc_skb(IEEE802154_BEACON_SKB_SZ, GFP_KERNEL);
+	if (!skb)
+		return -ENOBUFS;
+
+	beacon_req = rcu_dereference_protected(local->beacon_req,
+					       &local->beacon_lock);
+	sdata = IEEE802154_WPAN_DEV_TO_SUB_IF(beacon_req->wpan_dev);
+	skb->dev = sdata->dev;
+
+	ret = ieee802154_beacon_push(skb, &local->beacon);
+	if (ret) {
+		kfree_skb(skb);
+		return ret;
+	}
+
+	return ieee802154_mlme_tx_one(local, sdata, skb);
+}
+
+void mac802154_beacon_worker(struct work_struct *work)
+{
+	struct ieee802154_local *local =
+		container_of(work, struct ieee802154_local, beacon_work.work);
+	struct cfg802154_beacon_request *beacon_req;
+	int ret;
+
+	mutex_lock(&local->beacon_lock);
+
+	if (!mac802154_is_beaconing(local))
+		goto unlock_mutex;
+
+	if (local->suspended)
+		goto queue_work;
+
+	beacon_req = rcu_dereference_protected(local->beacon_req,
+					       &local->beacon_lock);
+
+	ret = mac802154_transmit_beacon_locked(local, beacon_req->wpan_dev);
+	if (ret)
+		pr_err("Error when transmitting beacon (%d)\n", ret);
+
+queue_work:
+	if (local->beacon_interval >= 0)
+		queue_delayed_work(local->workqueue, &local->beacon_work,
+				   local->beacon_interval);
+
+unlock_mutex:
+	mutex_unlock(&local->beacon_lock);
+}
+
+static void mac802154_end_beaconing(struct ieee802154_local *local)
+{
+	struct cfg802154_beacon_request *beacon_req;
+	struct ieee802154_sub_if_data *sdata;
+
+	beacon_req = rcu_dereference_protected(local->beacon_req,
+					       &local->beacon_lock);
+	sdata = IEEE802154_WPAN_DEV_TO_SUB_IF(beacon_req->wpan_dev);
+
+	if (local->beacon_interval >= 0)
+		cancel_delayed_work(&local->beacon_work);
+
+	clear_bit(IEEE802154_IS_BEACONING, &local->ongoing);
+	nl802154_end_beaconing(beacon_req->wpan_dev, beacon_req);
+}
+
+int mac802154_stop_beacons_locked(struct ieee802154_local *local)
+{
+	lockdep_assert_held(&local->beacon_lock);
+
+	if (!mac802154_is_beaconing(local))
+		return -ESRCH;
+
+	mac802154_end_beaconing(local);
+
+	return 0;
+}
+
+int mac802154_send_beacons_locked(struct ieee802154_sub_if_data *sdata,
+				  struct cfg802154_beacon_request *request)
+{
+	struct ieee802154_local *local = sdata->local;
+
+	lockdep_assert_held(&local->beacon_lock);
+
+	if (mac802154_is_beaconing(local))
+		mac802154_stop_beacons_locked(local);
+
+	/* Store scanning parameters */
+	rcu_assign_pointer(local->beacon_req, request);
+
+	set_bit(IEEE802154_IS_BEACONING, &local->ongoing);
+
+	memset(&local->beacon, 0, sizeof(local->beacon));
+	local->beacon.mhr.fc.type = IEEE802154_FC_TYPE_BEACON;
+	local->beacon.mhr.fc.security_enabled = 0;
+	local->beacon.mhr.fc.frame_pending = 0;
+	local->beacon.mhr.fc.ack_request = 0;
+	local->beacon.mhr.fc.intra_pan = 0;
+	local->beacon.mhr.fc.dest_addr_mode = IEEE802154_NO_ADDRESSING;
+	local->beacon.mhr.fc.version = IEEE802154_2003_STD;
+	local->beacon.mhr.fc.source_addr_mode = IEEE802154_EXTENDED_ADDRESSING;
+	atomic_set(&request->wpan_dev->bsn, -1);
+	local->beacon.mhr.source.mode = IEEE802154_ADDR_LONG;
+	local->beacon.mhr.source.pan_id = cpu_to_le16(request->wpan_dev->pan_id);
+	local->beacon.mhr.source.extended_addr = cpu_to_le64(request->wpan_dev->extended_addr);
+	local->beacon.mac_pl.beacon_order = request->interval;
+	local->beacon.mac_pl.superframe_order = request->interval;
+	local->beacon.mac_pl.final_cap_slot = 0xf;
+	local->beacon.mac_pl.battery_life_ext = 0;
+	/* TODO: Fill this field depending on the coordinator capacity */
+	local->beacon.mac_pl.pan_coordinator = 1;
+	local->beacon.mac_pl.assoc_permit = 0;
+
+	/* Start the beacon work */
+	local->beacon_interval =
+		mac802154_scan_get_channel_time(request->interval,
+						request->wpan_phy->symbol_duration);
+	queue_delayed_work(local->workqueue, &local->beacon_work, 0);
+
+	return 0;
+}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 13/20] net: ieee802154: Add support for user active scan requests
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
                   ` (11 preceding siblings ...)
  2022-07-01 14:30 ` [PATCH wpan-next 12/20] net: mac802154: Handle basic beaconing Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-01 14:30 ` [PATCH wpan-next 14/20] net: mac802154: Handle active scanning Miquel Raynal
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

In case a passive scan could not discover any PAN, a device may decide
to perform an active scan to force coordinators to send a BEACON
"immediately". Allow users to request to perform an active scan.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 net/ieee802154/nl802154.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
index ff8069415e67..9505e17e7ce7 100644
--- a/net/ieee802154/nl802154.c
+++ b/net/ieee802154/nl802154.c
@@ -1413,6 +1413,7 @@ static int nl802154_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 
 	type = nla_get_u8(info->attrs[NL802154_ATTR_SCAN_TYPE]);
 	switch (type) {
+	case NL802154_SCAN_ACTIVE:
 	case NL802154_SCAN_PASSIVE:
 		request->type = type;
 		break;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 14/20] net: mac802154: Handle active scanning
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
                   ` (12 preceding siblings ...)
  2022-07-01 14:30 ` [PATCH wpan-next 13/20] net: ieee802154: Add support for user active scan requests Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-01 14:30 ` [PATCH wpan-next 15/20] net: ieee802154: Add support for allowing to answer BEACON_REQ Miquel Raynal
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

Active scan support is based on the current passive scan support,
cheered up with beacon requests sent after every channel change.

Co-developed-by: David Girault <david.girault@qorvo.com>
Signed-off-by: David Girault <david.girault@qorvo.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 include/net/ieee802154_netdev.h | 18 ++++++++++-
 net/ieee802154/header_ops.c     | 27 ++++++++++++++++
 net/mac802154/ieee802154_i.h    |  1 +
 net/mac802154/scan.c            | 56 +++++++++++++++++++++++++++++++--
 4 files changed, 99 insertions(+), 3 deletions(-)

diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
index f7716aeec93b..21e7e3f66c82 100644
--- a/include/net/ieee802154_netdev.h
+++ b/include/net/ieee802154_netdev.h
@@ -58,6 +58,10 @@ struct ieee802154_beacon_hdr {
 #endif
 } __packed;
 
+struct ieee802154_mac_cmd_pl {
+	u8  cmd_id;
+} __packed;
+
 struct ieee802154_sechdr {
 #if defined(__LITTLE_ENDIAN_BITFIELD)
 	u8 level:3,
@@ -144,6 +148,16 @@ struct ieee802154_beacon_frame {
 	struct ieee802154_beacon_hdr mac_pl;
 };
 
+struct ieee802154_mac_cmd_frame {
+	struct ieee802154_hdr mhr;
+	struct ieee802154_mac_cmd_pl mac_pl;
+};
+
+struct ieee802154_beacon_req_frame {
+	struct ieee802154_hdr mhr;
+	struct ieee802154_mac_cmd_pl mac_pl;
+};
+
 /* pushes hdr onto the skb. fields of hdr->fc that can be calculated from
  * the contents of hdr will be, and the actual value of those bits in
  * hdr->fc will be ignored. this includes the INTRA_PAN bit and the frame
@@ -169,9 +183,11 @@ int ieee802154_hdr_peek_addrs(const struct sk_buff *skb,
  */
 int ieee802154_hdr_peek(const struct sk_buff *skb, struct ieee802154_hdr *hdr);
 
-/* pushes a beacon frame into an skb */
+/* pushes/pulls various frame types into/from an skb */
 int ieee802154_beacon_push(struct sk_buff *skb,
 			   struct ieee802154_beacon_frame *beacon);
+int ieee802154_mac_cmd_push(struct sk_buff *skb, void *frame,
+			    const void *pl, unsigned int pl_len);
 
 int ieee802154_max_payload(const struct ieee802154_hdr *hdr);
 
diff --git a/net/ieee802154/header_ops.c b/net/ieee802154/header_ops.c
index bab710aa36f9..795d46c7292d 100644
--- a/net/ieee802154/header_ops.c
+++ b/net/ieee802154/header_ops.c
@@ -121,6 +121,33 @@ ieee802154_hdr_push(struct sk_buff *skb, struct ieee802154_hdr *hdr)
 }
 EXPORT_SYMBOL_GPL(ieee802154_hdr_push);
 
+int ieee802154_mac_cmd_push(struct sk_buff *skb, void *f,
+			    const void *pl, unsigned int pl_len)
+{
+	struct ieee802154_mac_cmd_frame *frame = f;
+	struct ieee802154_mac_cmd_pl *mac_pl = &frame->mac_pl;
+	struct ieee802154_hdr *mhr = &frame->mhr;
+	u16 crc;
+	int ret;
+
+	skb_reserve(skb, sizeof(*mhr));
+	ret = ieee802154_hdr_push(skb, mhr);
+	if (ret < 0)
+		return ret;
+
+	skb_reset_mac_header(skb);
+	skb->mac_len = ret;
+
+	skb_put_data(skb, mac_pl, sizeof(*mac_pl));
+	skb_put_data(skb, pl, pl_len);
+
+	crc = crc_ccitt(0, skb->data, skb->len);
+	put_unaligned_le16(crc, skb_put(skb, 2));
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ieee802154_mac_cmd_push);
+
 int ieee802154_beacon_push(struct sk_buff *skb,
 			   struct ieee802154_beacon_frame *beacon)
 {
diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h
index f70848b60469..86a384942e6f 100644
--- a/net/mac802154/ieee802154_i.h
+++ b/net/mac802154/ieee802154_i.h
@@ -58,6 +58,7 @@ struct ieee802154_local {
 	/* Scanning */
 	struct mutex scan_lock;
 	int scan_channel_idx;
+	struct ieee802154_beacon_req_frame scan_beacon_req;
 	struct cfg802154_scan_request __rcu *scan_req;
 	struct delayed_work scan_work;
 
diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c
index 3dd11ec86d06..b9bb784bf388 100644
--- a/net/mac802154/scan.c
+++ b/net/mac802154/scan.c
@@ -18,10 +18,15 @@
 
 #define IEEE802154_BEACON_MHR_SZ 13
 #define IEEE802154_BEACON_PL_SZ 4
+#define IEEE802154_MAC_CMD_MHR_SZ 7
+#define IEEE802154_MAC_CMD_PL_SZ 1
 #define IEEE802154_CRC_SZ 2
 #define IEEE802154_BEACON_SKB_SZ (IEEE802154_BEACON_MHR_SZ + \
 				  IEEE802154_BEACON_PL_SZ + \
 				  IEEE802154_CRC_SZ)
+#define IEEE802154_MAC_CMD_SKB_SZ (IEEE802154_MAC_CMD_MHR_SZ + \
+				   IEEE802154_MAC_CMD_PL_SZ +  \
+				   IEEE802154_CRC_SZ)
 
 static bool mac802154_check_promiscuous(struct ieee802154_local *local)
 {
@@ -128,6 +133,44 @@ void mac802154_flush_queued_beacons(struct ieee802154_local *local)
 	}
 }
 
+static int mac802154_scan_prepare_beacon_req(struct ieee802154_local *local)
+{
+	memset(&local->scan_beacon_req, 0, sizeof(local->scan_beacon_req));
+	local->scan_beacon_req.mhr.fc.type = IEEE802154_FC_TYPE_MAC_CMD;
+	local->scan_beacon_req.mhr.fc.dest_addr_mode = IEEE802154_SHORT_ADDRESSING;
+	local->scan_beacon_req.mhr.fc.version = IEEE802154_2003_STD;
+	local->scan_beacon_req.mhr.fc.source_addr_mode = IEEE802154_NO_ADDRESSING;
+	local->scan_beacon_req.mhr.dest.mode = IEEE802154_ADDR_SHORT;
+	local->scan_beacon_req.mhr.dest.pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST);
+	local->scan_beacon_req.mhr.dest.short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
+	local->scan_beacon_req.mac_pl.cmd_id = IEEE802154_CMD_BEACON_REQ;
+
+	return 0;
+}
+
+static int mac802154_transmit_beacon_req_locked(struct ieee802154_local *local,
+						struct ieee802154_sub_if_data *sdata)
+{
+	struct sk_buff *skb;
+	int ret;
+
+	lockdep_assert_held(&local->scan_lock);
+
+	skb = alloc_skb(IEEE802154_MAC_CMD_SKB_SZ, GFP_KERNEL);
+	if (!skb)
+		return -ENOBUFS;
+
+	skb->dev = sdata->dev;
+
+	ret = ieee802154_mac_cmd_push(skb, &local->scan_beacon_req, NULL, 0);
+	if (ret) {
+		kfree_skb(skb);
+		return ret;
+	}
+
+	return ieee802154_mlme_tx(local, sdata, skb);
+}
+
 void mac802154_scan_worker(struct work_struct *work)
 {
 	struct ieee802154_local *local =
@@ -173,6 +216,12 @@ void mac802154_scan_worker(struct work_struct *work)
 		mac802154_flush_queued_beacons(local);
 	} while (ret);
 
+	if (scan_req->type == NL802154_SCAN_ACTIVE) {
+		ret = mac802154_transmit_beacon_req_locked(local, sdata);
+		if (ret)
+			pr_err("Error when transmitting beacon request (%d)\n", ret);
+	}
+
 queue_work:
 	scan_duration = mac802154_scan_get_channel_time(scan_req->duration,
 							local->phy->symbol_duration);
@@ -195,13 +244,16 @@ int mac802154_trigger_scan_locked(struct ieee802154_sub_if_data *sdata,
 	if (mac802154_is_scanning(local))
 		return -EBUSY;
 
-	/* TODO: support other scanning type */
-	if (request->type != NL802154_SCAN_PASSIVE)
+	if (request->type != NL802154_SCAN_PASSIVE &&
+	    request->type != NL802154_SCAN_ACTIVE)
 		return -EOPNOTSUPP;
 
 	/* Store scanning parameters */
 	rcu_assign_pointer(local->scan_req, request);
 
+	if (request->type == NL802154_SCAN_ACTIVE)
+		mac802154_scan_prepare_beacon_req(local);
+
 	/* Software scanning requires to set promiscuous mode, so we need to
 	 * pause the Tx queue during the entire operation.
 	 */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 15/20] net: ieee802154: Add support for allowing to answer BEACON_REQ
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
                   ` (13 preceding siblings ...)
  2022-07-01 14:30 ` [PATCH wpan-next 14/20] net: mac802154: Handle active scanning Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-01 14:30 ` [PATCH wpan-next 16/20] net: mac802154: Handle received BEACON_REQ Miquel Raynal
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

Accept beaconing configurations from the user which involve answering
beacon requests rather than only passively sending beacons. This may
help devices to find the PAN more quickly.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 net/ieee802154/nl802154.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
index 9505e17e7ce7..00b03c33e826 100644
--- a/net/ieee802154/nl802154.c
+++ b/net/ieee802154/nl802154.c
@@ -1594,7 +1594,7 @@ nl802154_send_beacons(struct sk_buff *skb, struct genl_info *info)
 
 	if (info->attrs[NL802154_ATTR_BEACON_INTERVAL]) {
 		request->interval = nla_get_u8(info->attrs[NL802154_ATTR_BEACON_INTERVAL]);
-		if (request->interval > IEEE802154_MAX_SCAN_DURATION) {
+		if (request->interval > IEEE802154_ACTIVE_SCAN_DURATION) {
 			pr_err("Interval is out of range\n");
 			err = -EINVAL;
 			goto free_request;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 16/20] net: mac802154: Handle received BEACON_REQ
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
                   ` (14 preceding siblings ...)
  2022-07-01 14:30 ` [PATCH wpan-next 15/20] net: ieee802154: Add support for allowing to answer BEACON_REQ Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-01 14:30 ` [PATCH wpan-next 17/20] net: ieee802154: Handle limited devices with only datagram support Miquel Raynal
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

When performing an active scan, devices emit BEACON_REQ which
must be answered by other PANs receiving the request, unless they are
already passively sending beacons.

Answering a beacon request becomes a duty when the user tells us to send
beacons and the request provides an interval of 15.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 include/net/ieee802154_netdev.h |  2 ++
 net/ieee802154/header_ops.c     | 13 +++++++
 net/mac802154/ieee802154_i.h    | 20 +++++++++++
 net/mac802154/main.c            |  2 ++
 net/mac802154/rx.c              | 62 ++++++++++++++++++++++++++++++++-
 net/mac802154/scan.c            | 12 ++++---
 6 files changed, 106 insertions(+), 5 deletions(-)

diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
index 21e7e3f66c82..d1152bff8b9b 100644
--- a/include/net/ieee802154_netdev.h
+++ b/include/net/ieee802154_netdev.h
@@ -188,6 +188,8 @@ int ieee802154_beacon_push(struct sk_buff *skb,
 			   struct ieee802154_beacon_frame *beacon);
 int ieee802154_mac_cmd_push(struct sk_buff *skb, void *frame,
 			    const void *pl, unsigned int pl_len);
+int ieee802154_mac_cmd_pl_pull(struct sk_buff *skb,
+			       struct ieee802154_mac_cmd_pl *mac_pl);
 
 int ieee802154_max_payload(const struct ieee802154_hdr *hdr);
 
diff --git a/net/ieee802154/header_ops.c b/net/ieee802154/header_ops.c
index 795d46c7292d..8d81221dd119 100644
--- a/net/ieee802154/header_ops.c
+++ b/net/ieee802154/header_ops.c
@@ -316,6 +316,19 @@ ieee802154_hdr_pull(struct sk_buff *skb, struct ieee802154_hdr *hdr)
 }
 EXPORT_SYMBOL_GPL(ieee802154_hdr_pull);
 
+int ieee802154_mac_cmd_pl_pull(struct sk_buff *skb,
+			       struct ieee802154_mac_cmd_pl *mac_pl)
+{
+	if (!pskb_may_pull(skb, sizeof(*mac_pl)))
+		return -EINVAL;
+
+	memcpy(mac_pl, skb->data, sizeof(*mac_pl));
+	skb_pull(skb, sizeof(*mac_pl));
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ieee802154_mac_cmd_pl_pull);
+
 int
 ieee802154_hdr_peek_addrs(const struct sk_buff *skb, struct ieee802154_hdr *hdr)
 {
diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h
index 86a384942e6f..a366d4901d70 100644
--- a/net/mac802154/ieee802154_i.h
+++ b/net/mac802154/ieee802154_i.h
@@ -72,6 +72,8 @@ struct ieee802154_local {
 	/* Asynchronous tasks */
 	struct list_head rx_beacon_list;
 	struct work_struct rx_beacon_work;
+	struct list_head rx_mac_cmd_list;
+	struct work_struct rx_mac_cmd_work;
 
 	bool started;
 	bool suspended;
@@ -146,6 +148,22 @@ ieee802154_sdata_running(struct ieee802154_sub_if_data *sdata)
 	return test_bit(SDATA_STATE_RUNNING, &sdata->state);
 }
 
+static inline int ieee802154_get_mac_cmd(struct sk_buff *skb, u8 *mac_cmd)
+{
+	struct ieee802154_mac_cmd_pl mac_pl;
+	int ret;
+
+	if (mac_cb(skb)->type != IEEE802154_FC_TYPE_MAC_CMD)
+		return -EINVAL;
+
+	ret = ieee802154_mac_cmd_pl_pull(skb, &mac_pl);
+	if (ret)
+		return ret;
+
+	*mac_cmd = mac_pl.cmd_id;
+	return 0;
+}
+
 extern struct ieee802154_mlme_ops mac802154_mlme_wpan;
 
 void ieee802154_rx(struct ieee802154_local *local, struct sk_buff *skb);
@@ -258,6 +276,8 @@ static inline bool mac802154_is_beaconing(struct ieee802154_local *local)
 	return test_bit(IEEE802154_IS_BEACONING, &local->ongoing);
 }
 
+void mac802154_rx_mac_cmd_worker(struct work_struct *work);
+
 /* interface handling */
 int ieee802154_iface_init(void);
 void ieee802154_iface_exit(void);
diff --git a/net/mac802154/main.c b/net/mac802154/main.c
index 826a0d2ce395..a6ffae53d53c 100644
--- a/net/mac802154/main.c
+++ b/net/mac802154/main.c
@@ -90,6 +90,7 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
 
 	INIT_LIST_HEAD(&local->interfaces);
 	INIT_LIST_HEAD(&local->rx_beacon_list);
+	INIT_LIST_HEAD(&local->rx_mac_cmd_list);
 	mutex_init(&local->iflist_mtx);
 	mutex_init(&local->device_lock);
 	mutex_init(&local->scan_lock);
@@ -103,6 +104,7 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
 	INIT_DELAYED_WORK(&local->scan_work, mac802154_scan_worker);
 	INIT_WORK(&local->rx_beacon_work, mac802154_rx_beacon_worker);
 	INIT_DELAYED_WORK(&local->beacon_work, mac802154_beacon_worker);
+	INIT_WORK(&local->rx_mac_cmd_work, mac802154_rx_mac_cmd_worker);
 
 	/* init supported flags with 802.15.4 default ranges */
 	phy->supported.max_minbe = 8;
diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
index 0b1cf8c85ee9..4688ce00ba9c 100644
--- a/net/mac802154/rx.c
+++ b/net/mac802154/rx.c
@@ -53,6 +53,55 @@ void mac802154_rx_beacon_worker(struct work_struct *work)
 	mutex_unlock(&local->scan_lock);
 }
 
+static bool mac802154_should_answer_beacon_req(struct ieee802154_local *local)
+{
+	struct cfg802154_beacon_request *beacon_req;
+	unsigned int interval;
+
+	if (!mac802154_is_beaconing(local))
+		return false;
+
+	mutex_lock(&local->beacon_lock);
+	beacon_req = rcu_dereference_protected(local->beacon_req,
+					       &local->beacon_lock);
+	interval = beacon_req->interval;
+	mutex_unlock(&local->beacon_lock);
+
+	return interval == IEEE802154_ACTIVE_SCAN_DURATION;
+}
+
+void mac802154_rx_mac_cmd_worker(struct work_struct *work)
+{
+	struct ieee802154_local *local =
+		container_of(work, struct ieee802154_local, rx_mac_cmd_work);
+	struct cfg802154_mac_pkt *mac_pkt;
+	u8 mac_cmd;
+	int rc;
+
+	mac_pkt = list_first_entry(&local->rx_mac_cmd_list,
+				   struct cfg802154_mac_pkt, node);
+
+	rc = ieee802154_get_mac_cmd(mac_pkt->skb, &mac_cmd);
+	if (rc)
+		goto out;
+
+	switch (mac_cmd) {
+	case IEEE802154_CMD_BEACON_REQ:
+		if (!mac802154_should_answer_beacon_req(local))
+			break;
+
+		queue_delayed_work(local->workqueue, &local->beacon_work, 0);
+		break;
+	default:
+		break;
+	}
+
+out:
+	list_del(&mac_pkt->node);
+	kfree_skb(mac_pkt->skb);
+	kfree(mac_pkt);
+}
+
 static int
 ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata,
 		       struct sk_buff *skb, const struct ieee802154_hdr *hdr)
@@ -131,8 +180,19 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata,
 		list_add_tail(&mac_pkt->node, &sdata->local->rx_beacon_list);
 		queue_work(sdata->local->workqueue, &sdata->local->rx_beacon_work);
 		goto success;
-	case IEEE802154_FC_TYPE_ACK:
+
 	case IEEE802154_FC_TYPE_MAC_CMD:
+		mac_pkt = kzalloc(sizeof(*mac_pkt), GFP_ATOMIC);
+		if (!mac_pkt)
+			goto fail;
+
+		mac_pkt->skb = skb_get(skb);
+		mac_pkt->sdata = sdata;
+		list_add_tail(&mac_pkt->node, &sdata->local->rx_mac_cmd_list);
+		queue_work(sdata->local->workqueue, &sdata->local->rx_mac_cmd_work);
+		goto success;
+
+	case IEEE802154_FC_TYPE_ACK:
 		goto fail;
 
 	case IEEE802154_FC_TYPE_DATA:
diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c
index b9bb784bf388..c102184e8de4 100644
--- a/net/mac802154/scan.c
+++ b/net/mac802154/scan.c
@@ -376,7 +376,7 @@ void mac802154_beacon_worker(struct work_struct *work)
 		pr_err("Error when transmitting beacon (%d)\n", ret);
 
 queue_work:
-	if (local->beacon_interval >= 0)
+	if (beacon_req->interval < IEEE802154_ACTIVE_SCAN_DURATION)
 		queue_delayed_work(local->workqueue, &local->beacon_work,
 				   local->beacon_interval);
 
@@ -393,7 +393,7 @@ static void mac802154_end_beaconing(struct ieee802154_local *local)
 					       &local->beacon_lock);
 	sdata = IEEE802154_WPAN_DEV_TO_SUB_IF(beacon_req->wpan_dev);
 
-	if (local->beacon_interval >= 0)
+	if (beacon_req->interval < IEEE802154_ACTIVE_SCAN_DURATION)
 		cancel_delayed_work(&local->beacon_work);
 
 	clear_bit(IEEE802154_IS_BEACONING, &local->ongoing);
@@ -441,13 +441,17 @@ int mac802154_send_beacons_locked(struct ieee802154_sub_if_data *sdata,
 	local->beacon.mhr.source.pan_id = cpu_to_le16(request->wpan_dev->pan_id);
 	local->beacon.mhr.source.extended_addr = cpu_to_le64(request->wpan_dev->extended_addr);
 	local->beacon.mac_pl.beacon_order = request->interval;
-	local->beacon.mac_pl.superframe_order = request->interval;
+	if (request->interval <= IEEE802154_MAX_SCAN_DURATION)
+		local->beacon.mac_pl.superframe_order = request->interval;
 	local->beacon.mac_pl.final_cap_slot = 0xf;
 	local->beacon.mac_pl.battery_life_ext = 0;
-	/* TODO: Fill this field depending on the coordinator capacity */
+	/* TODO: Fill this field with the coordinator situation in the network */
 	local->beacon.mac_pl.pan_coordinator = 1;
 	local->beacon.mac_pl.assoc_permit = 0;
 
+	if (request->interval == IEEE802154_ACTIVE_SCAN_DURATION)
+		return 0;
+
 	/* Start the beacon work */
 	local->beacon_interval =
 		mac802154_scan_get_channel_time(request->interval,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 17/20] net: ieee802154: Handle limited devices with only datagram support
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
                   ` (15 preceding siblings ...)
  2022-07-01 14:30 ` [PATCH wpan-next 16/20] net: mac802154: Handle received BEACON_REQ Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-15  3:16   ` Alexander Aring
  2022-07-01 14:30 ` [PATCH wpan-next 18/20] ieee802154: ca8210: Flag the driver as being limited Miquel Raynal
                   ` (3 subsequent siblings)
  20 siblings, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

Some devices, like HardMAC ones can be a bit limited in the way they
handle mac commands. In particular, they might just not support it at
all and instead only be able to transmit and receive regular data
packets. In this case, they cannot be used for any of the internal
management commands that we have introduced so far and must be flagged
accordingly.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 include/net/cfg802154.h   | 3 +++
 net/ieee802154/nl802154.c | 6 ++++++
 2 files changed, 9 insertions(+)

diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index d6ff60d900a9..20ac4df9dc7b 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -178,12 +178,15 @@ wpan_phy_cca_cmp(const struct wpan_phy_cca *a, const struct wpan_phy_cca *b)
  *	setting.
  * @WPAN_PHY_FLAG_STATE_QUEUE_STOPPED: Indicates that the transmit queue was
  *	temporarily stopped.
+ * @WPAN_PHY_FLAG_DATAGRAMS_ONLY: Indicates that transceiver is only able to
+ *	send/receive datagrams.
  */
 enum wpan_phy_flags {
 	WPAN_PHY_FLAG_TXPOWER		= BIT(1),
 	WPAN_PHY_FLAG_CCA_ED_LEVEL	= BIT(2),
 	WPAN_PHY_FLAG_CCA_MODE		= BIT(3),
 	WPAN_PHY_FLAG_STATE_QUEUE_STOPPED = BIT(4),
+	WPAN_PHY_FLAG_DATAGRAMS_ONLY	= BIT(5),
 };
 
 struct wpan_phy {
diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
index 00b03c33e826..b31a0bd36b08 100644
--- a/net/ieee802154/nl802154.c
+++ b/net/ieee802154/nl802154.c
@@ -1404,6 +1404,9 @@ static int nl802154_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
 		return -EPERM;
 
+	if (wpan_phy->flags & WPAN_PHY_FLAG_DATAGRAMS_ONLY)
+		return -EOPNOTSUPP;
+
 	request = kzalloc(sizeof(*request), GFP_KERNEL);
 	if (!request)
 		return -ENOMEM;
@@ -1585,6 +1588,9 @@ nl802154_send_beacons(struct sk_buff *skb, struct genl_info *info)
 		return -EPERM;
 	}
 
+	if (wpan_phy->flags & WPAN_PHY_FLAG_DATAGRAMS_ONLY)
+		return -EOPNOTSUPP;
+
 	request = kzalloc(sizeof(*request), GFP_KERNEL);
 	if (!request)
 		return -ENOMEM;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 18/20] ieee802154: ca8210: Flag the driver as being limited
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
                   ` (16 preceding siblings ...)
  2022-07-01 14:30 ` [PATCH wpan-next 17/20] net: ieee802154: Handle limited devices with only datagram support Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-01 14:30 ` [PATCH wpan-next 19/20] ieee802154: hwsim: Do not check the rtnl Miquel Raynal
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

This is a hardMAC device wired to Linux 802154 softMAC
implementation. It is a bit limited in the sense that it cannot handle
anything else that datagrams. Let's flag it like this to prevent using
unsupported features such as scan/beacons handling.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/net/ieee802154/ca8210.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c
index 42c0b451088d..12f3564c8f8d 100644
--- a/drivers/net/ieee802154/ca8210.c
+++ b/drivers/net/ieee802154/ca8210.c
@@ -2943,7 +2943,8 @@ static void ca8210_hw_setup(struct ieee802154_hw *ca8210_hw)
 	ca8210_hw->phy->flags =
 		WPAN_PHY_FLAG_TXPOWER |
 		WPAN_PHY_FLAG_CCA_ED_LEVEL |
-		WPAN_PHY_FLAG_CCA_MODE;
+		WPAN_PHY_FLAG_CCA_MODE |
+		WPAN_PHY_FLAG_DATAGRAMS_ONLY;
 }
 
 /**
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 19/20] ieee802154: hwsim: Do not check the rtnl
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
                   ` (17 preceding siblings ...)
  2022-07-01 14:30 ` [PATCH wpan-next 18/20] ieee802154: ca8210: Flag the driver as being limited Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-06  1:23   ` Alexander Aring
  2022-07-01 14:30 ` [PATCH wpan-next 20/20] ieee802154: hwsim: Allow devices to be coordinators Miquel Raynal
  2022-07-04  1:17 ` [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Alexander Aring
  20 siblings, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

There is no need to ensure the rtnl is locked when changing a driver's
channel. This cause issues when scanning and this is the only driver
relying on it. Just drop this dependency because it does not seem
legitimate.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/net/ieee802154/mac802154_hwsim.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c
index 38c217bd7c82..a5b9fc2fb64c 100644
--- a/drivers/net/ieee802154/mac802154_hwsim.c
+++ b/drivers/net/ieee802154/mac802154_hwsim.c
@@ -100,7 +100,7 @@ static int hwsim_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
 	pib->page = page;
 	pib->channel = channel;
 
-	pib_old = rtnl_dereference(phy->pib);
+	rcu_assign_pointer(pib_old, phy->pib);
 	rcu_assign_pointer(phy->pib, pib);
 	kfree_rcu(pib_old, rcu);
 	return 0;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH wpan-next 20/20] ieee802154: hwsim: Allow devices to be coordinators
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
                   ` (18 preceding siblings ...)
  2022-07-01 14:30 ` [PATCH wpan-next 19/20] ieee802154: hwsim: Do not check the rtnl Miquel Raynal
@ 2022-07-01 14:30 ` Miquel Raynal
  2022-07-11  2:01   ` Alexander Aring
  2022-07-04  1:17 ` [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Alexander Aring
  20 siblings, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-07-01 14:30 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	netdev, David Girault, Romuald Despres, Frederic Blain,
	Nicolas Schodet, Thomas Petazzoni, Miquel Raynal

In order to be able to create coordinator interfaces, we need the
drivers to advertize that they support this type of interface. Fill in
the right bit in the hwsim capabilities to allow the creation of these
coordinator interfaces.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/net/ieee802154/mac802154_hwsim.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c
index a5b9fc2fb64c..a678ede07219 100644
--- a/drivers/net/ieee802154/mac802154_hwsim.c
+++ b/drivers/net/ieee802154/mac802154_hwsim.c
@@ -776,6 +776,8 @@ static int hwsim_add_one(struct genl_info *info, struct device *dev,
 	/* 950 MHz GFSK 802.15.4d-2009 */
 	hw->phy->supported.channels[6] |= 0x3ffc00;
 
+	hw->phy->supported.iftypes |= BIT(NL802154_IFTYPE_COORD);
+
 	ieee802154_random_extended_addr(&hw->phy->perm_extended_addr);
 
 	/* hwsim phy channel 13 as default */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 09/20] net: mac802154: Introduce a global device lock
  2022-07-01 14:30 ` [PATCH wpan-next 09/20] net: mac802154: Introduce a global device lock Miquel Raynal
@ 2022-07-04  1:12   ` Alexander Aring
  2022-08-19 17:06     ` Miquel Raynal
  0 siblings, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-07-04  1:12 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> The purpose of this device lock is to prevent the removal of the device
> while an asynchronous MLME operation happens. The RTNL works well for
> that but in a later series having the RTNL taken here will be
> problematic and will cause lockdep to warn us about a circular
> dependency. We don't really need the RTNL here, just a serialization
> over this operation.
>
> Replace the RTNL calls with this new lock.

I am unhappy about this solution. Can we not interrupt the ongoing
operation "scan" here and come to an end at a stop?

The RTNL is NOT only to prevent the removal of something... If mostly
all operations are protected by and I know one which makes trouble
here... setting page/channel. I know we don't hold the rtnl lock on
other transmit functionality for phy settings which has other reasons
why we allow it... but here we offer a mac operation which delivers
wrong results if somebody does another setting e.g. set page/channel
while scan is going on and we should prevent this.

Dropping the rtnl lock, yes we can do that... I cannot think about all
the side effects which this change will bring into, one I know is the
channel setting, mostly everything that is interfering with a scan and
then ugly things which we don't want... preparing the code for the
page/channel gives us a direction on how to fix and check the other
cases if we find them. btw: we should do this on another approach
anyway because the rtnl lock is not held during a whole operation and
we don't want that.

We should also take care that we hold some references which we held
during the scan, even if it's protected by stop (just for
correctness).

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing
  2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
                   ` (19 preceding siblings ...)
  2022-07-01 14:30 ` [PATCH wpan-next 20/20] ieee802154: hwsim: Allow devices to be coordinators Miquel Raynal
@ 2022-07-04  1:17 ` Alexander Aring
  20 siblings, 0 replies; 84+ messages in thread
From: Alexander Aring @ 2022-07-04  1:17 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> Hello,
>
> After a few exchanges about inter-PAN management with Alexander, it was
> decided that most of this series would be dropped, because the kernel
> should in the end not really care about keeping a local copy of the
> discovered coordinators, this is userspace job.
>
> So here is a "first" version of the scanning series which hopefully
> meets the main requirements discussed the past days on the mailing
> list. I know it is rather big, but there are a few very trivial patches
> there, so here is how it is built:

I have probably more to say about this patch series, but I need more
days to look into it closely. So maybe we can first discuss here more
about things I comment on and have questions about it.

Thanks.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 19/20] ieee802154: hwsim: Do not check the rtnl
  2022-07-01 14:30 ` [PATCH wpan-next 19/20] ieee802154: hwsim: Do not check the rtnl Miquel Raynal
@ 2022-07-06  1:23   ` Alexander Aring
  2022-08-01 23:58     ` Alexander Aring
  2022-08-19 17:09     ` Miquel Raynal
  0 siblings, 2 replies; 84+ messages in thread
From: Alexander Aring @ 2022-07-06  1:23 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Fri, Jul 1, 2022 at 10:37 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> There is no need to ensure the rtnl is locked when changing a driver's
> channel. This cause issues when scanning and this is the only driver
> relying on it. Just drop this dependency because it does not seem
> legitimate.
>

switching channels relies on changing pib attributes, pib attributes
are protected by rtnl. If you experience issues here then it's
probably because you do something wrong. All drivers assuming here
that rtnl lock is held.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-07-01 14:30 ` [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces Miquel Raynal
@ 2022-07-06  1:51   ` Alexander Aring
  2022-08-19 17:11     ` Miquel Raynal
  0 siblings, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-07-06  1:51 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> As a first strep in introducing proper PAN management and association,
> we need to be able to create coordinator interfaces which might act as
> coordinator or PAN coordinator.
>
> Hence, let's add the minimum support to allow the creation of these
> interfaces. This might be restrained and improved later.
>
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> ---
>  net/mac802154/iface.c | 14 ++++++++------
>  net/mac802154/rx.c    |  2 +-
>  2 files changed, 9 insertions(+), 7 deletions(-)
>
> diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
> index 500ed1b81250..7ac0c5685d3f 100644
> --- a/net/mac802154/iface.c
> +++ b/net/mac802154/iface.c
> @@ -273,13 +273,13 @@ ieee802154_check_concurrent_iface(struct ieee802154_sub_if_data *sdata,
>                 if (nsdata != sdata && ieee802154_sdata_running(nsdata)) {
>                         int ret;
>
> -                       /* TODO currently we don't support multiple node types
> -                        * we need to run skb_clone at rx path. Check if there
> -                        * exist really an use case if we need to support
> -                        * multiple node types at the same time.
> +                       /* TODO currently we don't support multiple node/coord
> +                        * types we need to run skb_clone at rx path. Check if
> +                        * there exist really an use case if we need to support
> +                        * multiple node/coord types at the same time.
>                          */
> -                       if (wpan_dev->iftype == NL802154_IFTYPE_NODE &&
> -                           nsdata->wpan_dev.iftype == NL802154_IFTYPE_NODE)
> +                       if (wpan_dev->iftype != NL802154_IFTYPE_MONITOR &&
> +                           nsdata->wpan_dev.iftype != NL802154_IFTYPE_MONITOR)
>                                 return -EBUSY;
>
>                         /* check all phy mac sublayer settings are the same.
> @@ -577,6 +577,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
>         wpan_dev->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
>
>         switch (type) {
> +       case NL802154_IFTYPE_COORD:
>         case NL802154_IFTYPE_NODE:
>                 ieee802154_be64_to_le64(&wpan_dev->extended_addr,
>                                         sdata->dev->dev_addr);
> @@ -636,6 +637,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
>         ieee802154_le64_to_be64(ndev->perm_addr,
>                                 &local->hw.phy->perm_extended_addr);
>         switch (type) {
> +       case NL802154_IFTYPE_COORD:
>         case NL802154_IFTYPE_NODE:
>                 ndev->type = ARPHRD_IEEE802154;
>                 if (ieee802154_is_valid_extended_unicast_addr(extended_addr)) {
> diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
> index b8ce84618a55..39459d8d787a 100644
> --- a/net/mac802154/rx.c
> +++ b/net/mac802154/rx.c
> @@ -203,7 +203,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
>         }
>
>         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
>                         continue;

I probably get why you are doing that, but first the overall design is
working differently - means you should add an additional receive path
for the special interface type.

Also we "discovered" before that the receive path of node vs
coordinator is different... Where is the different handling here? I
don't see it, I see that NODE and COORD are the same now (because that
is _currently_ everything else than monitor). This change is not
enough and does "something" to handle in some way coordinator receive
path but there are things missing.

1. Changing the address filters that it signals the transceiver it's
acting as coordinator
2. We _should_ also have additional handling for whatever the
additional handling what address filters are doing in mac802154
_because_ there is hardware which doesn't have address filtering e.g.
hwsim which depend that this is working in software like other
transceiver hardware address filters.

For the 2. one, I don't know if we do that even for NODE right or we
just have the bare minimal support there... I don't assume that
everything is working correctly here but what I want to see is a
separate receive path for coordinators that people can send patches to
fix it.

Thanks.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 20/20] ieee802154: hwsim: Allow devices to be coordinators
  2022-07-01 14:30 ` [PATCH wpan-next 20/20] ieee802154: hwsim: Allow devices to be coordinators Miquel Raynal
@ 2022-07-11  2:01   ` Alexander Aring
  2022-08-19 17:12     ` Miquel Raynal
  0 siblings, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-07-11  2:01 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Fri, Jul 1, 2022 at 10:37 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> In order to be able to create coordinator interfaces, we need the
> drivers to advertize that they support this type of interface. Fill in
> the right bit in the hwsim capabilities to allow the creation of these
> coordinator interfaces.
>
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> ---
>  drivers/net/ieee802154/mac802154_hwsim.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c
> index a5b9fc2fb64c..a678ede07219 100644
> --- a/drivers/net/ieee802154/mac802154_hwsim.c
> +++ b/drivers/net/ieee802154/mac802154_hwsim.c
> @@ -776,6 +776,8 @@ static int hwsim_add_one(struct genl_info *info, struct device *dev,
>         /* 950 MHz GFSK 802.15.4d-2009 */
>         hw->phy->supported.channels[6] |= 0x3ffc00;
>
> +       hw->phy->supported.iftypes |= BIT(NL802154_IFTYPE_COORD);

I think we can do that for more than one driver (except ca8210). What
about the other iftypes?

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 05/20] net: ieee802154: Define frame types
  2022-07-01 14:30 ` [PATCH wpan-next 05/20] net: ieee802154: Define frame types Miquel Raynal
@ 2022-07-11  2:06   ` Alexander Aring
  2022-08-19 17:13     ` Miquel Raynal
  0 siblings, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-07-11  2:06 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> A 802.15.4 frame can be of different types, here is a definition
> matching the specification. This enumeration will be soon be used when
> adding scanning support.
>
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> ---
>  include/net/ieee802154_netdev.h | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>
> diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
> index d0d188c3294b..13167851b1c3 100644
> --- a/include/net/ieee802154_netdev.h
> +++ b/include/net/ieee802154_netdev.h
> @@ -69,6 +69,17 @@ struct ieee802154_hdr_fc {
>  #endif
>  };
>
> +enum ieee802154_frame_type {
> +       IEEE802154_BEACON_FRAME,
> +       IEEE802154_DATA_FRAME,
> +       IEEE802154_ACKNOWLEDGEMENT_FRAME,
> +       IEEE802154_MAC_COMMAND_FRAME,
> +       IEEE802154_RESERVED_FRAME,
> +       IEEE802154_MULTIPURPOSE_FRAME,
> +       IEEE802154_FRAGMENT_FRAME,
> +       IEEE802154_EXTENDED_FRAME,
> +};

Please use and extend include/linux/ieee802154.h e.g. IEEE802154_FC_TYPE_DATA.
I am also not a fan of putting those structs on payload, because there
can be several problems with it, we should introduce inline helpers to
check/get each individual fields but... the struct is currently how
it's implemented.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 17/20] net: ieee802154: Handle limited devices with only datagram support
  2022-07-01 14:30 ` [PATCH wpan-next 17/20] net: ieee802154: Handle limited devices with only datagram support Miquel Raynal
@ 2022-07-15  3:16   ` Alexander Aring
  2022-08-19 17:13     ` Miquel Raynal
  0 siblings, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-07-15  3:16 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Fri, Jul 1, 2022 at 10:37 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> Some devices, like HardMAC ones can be a bit limited in the way they
> handle mac commands. In particular, they might just not support it at
> all and instead only be able to transmit and receive regular data
> packets. In this case, they cannot be used for any of the internal
> management commands that we have introduced so far and must be flagged
> accordingly.
>
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> ---
>  include/net/cfg802154.h   | 3 +++
>  net/ieee802154/nl802154.c | 6 ++++++
>  2 files changed, 9 insertions(+)
>
> diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
> index d6ff60d900a9..20ac4df9dc7b 100644
> --- a/include/net/cfg802154.h
> +++ b/include/net/cfg802154.h
> @@ -178,12 +178,15 @@ wpan_phy_cca_cmp(const struct wpan_phy_cca *a, const struct wpan_phy_cca *b)
>   *     setting.
>   * @WPAN_PHY_FLAG_STATE_QUEUE_STOPPED: Indicates that the transmit queue was
>   *     temporarily stopped.
> + * @WPAN_PHY_FLAG_DATAGRAMS_ONLY: Indicates that transceiver is only able to
> + *     send/receive datagrams.
>   */
>  enum wpan_phy_flags {
>         WPAN_PHY_FLAG_TXPOWER           = BIT(1),
>         WPAN_PHY_FLAG_CCA_ED_LEVEL      = BIT(2),
>         WPAN_PHY_FLAG_CCA_MODE          = BIT(3),
>         WPAN_PHY_FLAG_STATE_QUEUE_STOPPED = BIT(4),
> +       WPAN_PHY_FLAG_DATAGRAMS_ONLY    = BIT(5),
>  };
>
>  struct wpan_phy {
> diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
> index 00b03c33e826..b31a0bd36b08 100644
> --- a/net/ieee802154/nl802154.c
> +++ b/net/ieee802154/nl802154.c
> @@ -1404,6 +1404,9 @@ static int nl802154_trigger_scan(struct sk_buff *skb, struct genl_info *info)
>         if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
>                 return -EPERM;
>
> +       if (wpan_phy->flags & WPAN_PHY_FLAG_DATAGRAMS_ONLY)
> +               return -EOPNOTSUPP;
> +

for doing a scan it's also required to turn the transceiver into
promiscuous mode, right?

There is currently a flag if a driver supports promiscuous mode or
not... I am not sure if all drivers have support for it. For me it
looks like a mandatory feature but I am not sure if every driver
supports it.
We have a similar situation with acknowledge retransmit handling...
some transceivers can't handle it and for normal dataframes we have a
default behaviour that we don't set it. However sometimes it's
required by the spec, then we can't do anything here.

I think we should check on it but we should plan to drop this flag if
promiscuous mode is supported or not. I also think that the
promiscuous driver_ops should be removed and moved as a parameter for
start() driver_ops to declare which "receive mode" should be
enabled... but we can do that in due course.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 10/20] net: mac802154: Handle passive scanning
  2022-07-01 14:30 ` [PATCH wpan-next 10/20] net: mac802154: Handle passive scanning Miquel Raynal
@ 2022-07-15  3:33   ` Alexander Aring
  2022-07-15  3:42     ` Alexander Aring
  2022-08-01 23:42     ` Alexander Aring
  0 siblings, 2 replies; 84+ messages in thread
From: Alexander Aring @ 2022-07-15  3:33 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> Implement the core hooks in order to provide the softMAC layer support
> for passive scans. Scans are requested by the user and can be aborted.
>
> Changing the channels is prohibited during the scan.
>
> As transceivers enter promiscuous mode during scans, they might stop
> checking frame validity so we ensure this gets done at mac level.
>
> The implementation uses a workqueue triggered at a certain interval
> depending on the symbol duration for the current channel and the
> duration order provided.
>
> Received beacons during a passive scan are processed also in a work
> queue and forwarded to the upper layer.
>
> Active scanning is not supported yet.
>
> Co-developed-by: David Girault <david.girault@qorvo.com>
> Signed-off-by: David Girault <david.girault@qorvo.com>
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> ---
>  include/linux/ieee802154.h   |   4 +
>  include/net/cfg802154.h      |  12 ++
>  net/mac802154/Makefile       |   2 +-
>  net/mac802154/cfg.c          |  39 ++++++
>  net/mac802154/ieee802154_i.h |  29 ++++
>  net/mac802154/iface.c        |   6 +
>  net/mac802154/main.c         |   4 +
>  net/mac802154/rx.c           |  49 ++++++-
>  net/mac802154/scan.c         | 264 +++++++++++++++++++++++++++++++++++
>  9 files changed, 405 insertions(+), 4 deletions(-)
>  create mode 100644 net/mac802154/scan.c
>
> diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h
> index 929d4e672575..94bfee22bd0a 100644
> --- a/include/linux/ieee802154.h
> +++ b/include/linux/ieee802154.h
> @@ -47,6 +47,10 @@
>  /* Duration in superframe order */
>  #define IEEE802154_MAX_SCAN_DURATION   14
>  #define IEEE802154_ACTIVE_SCAN_DURATION        15
> +/* Superframe duration in slots */
> +#define IEEE802154_SUPERFRAME_PERIOD   16
> +/* Various periods expressed in symbols */
> +#define IEEE802154_SLOT_PERIOD         60
>  #define IEEE802154_LIFS_PERIOD         40
>  #define IEEE802154_SIFS_PERIOD         12
>  #define IEEE802154_MAX_SIFS_FRAME_SIZE 18
> diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
> index f05ce3c45b5d..206283fd4b72 100644
> --- a/include/net/cfg802154.h
> +++ b/include/net/cfg802154.h
> @@ -300,6 +300,18 @@ struct cfg802154_scan_request {
>         struct wpan_phy *wpan_phy;
>  };
>
> +/**
> + * struct cfg802154_mac_pkt - MAC packet descriptor (beacon/command)
> + * @node: MAC packets to process list member
> + * @skb: the received sk_buff
> + * @sdata: the interface on which @skb was received
> + */
> +struct cfg802154_mac_pkt {
> +       struct list_head node;
> +       struct sk_buff *skb;
> +       struct ieee802154_sub_if_data *sdata;
> +};
> +
>  struct ieee802154_llsec_key_id {
>         u8 mode;
>         u8 id;
> diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile
> index 4059295fdbf8..43d1347b37ee 100644
> --- a/net/mac802154/Makefile
> +++ b/net/mac802154/Makefile
> @@ -1,6 +1,6 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  obj-$(CONFIG_MAC802154)        += mac802154.o
>  mac802154-objs         := main.o rx.o tx.o mac_cmd.o mib.o \
> -                          iface.o llsec.o util.o cfg.o trace.o
> +                          iface.o llsec.o util.o cfg.o scan.o trace.o
>
>  CFLAGS_trace.o := -I$(src)
> diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c
> index 4116a894c86e..1f532d93d870 100644
> --- a/net/mac802154/cfg.c
> +++ b/net/mac802154/cfg.c
> @@ -114,6 +114,10 @@ ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel)
>             wpan_phy->current_channel == channel)
>                 return 0;
>
> +       /* Refuse to change channels during a scanning operation */
> +       if (mac802154_is_scanning(local))
> +               return -EBUSY;
> +

okay, that answered one of my other questions in another mail.

>         ret = drv_set_channel(local, page, channel);
>         if (!ret) {
>                 wpan_phy->current_page = page;
> @@ -261,6 +265,39 @@ ieee802154_set_ackreq_default(struct wpan_phy *wpan_phy,
>         return 0;
>  }
>
> +static int mac802154_trigger_scan(struct wpan_phy *wpan_phy,
> +                                 struct cfg802154_scan_request *request)
> +{
> +       struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
> +       struct ieee802154_sub_if_data *sdata;
> +       int ret;
> +
> +       sdata = IEEE802154_WPAN_DEV_TO_SUB_IF(request->wpan_dev);
> +
> +       ASSERT_RTNL();
> +
> +       mutex_lock(&local->scan_lock);
> +       ret = mac802154_trigger_scan_locked(sdata, request);
> +       mutex_unlock(&local->scan_lock);
> +
> +       return ret;
> +}
> +
> +static int mac802154_abort_scan(struct wpan_phy *wpan_phy,
> +                               struct wpan_dev *wpan_dev)
> +{
> +       struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
> +       int ret;
> +
> +       ASSERT_RTNL();
> +
> +       mutex_lock(&local->scan_lock);
> +       ret = mac802154_abort_scan_locked(local);
> +       mutex_unlock(&local->scan_lock);
> +
> +       return ret;
> +}
> +
>  #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
>  static void
>  ieee802154_get_llsec_table(struct wpan_phy *wpan_phy,
> @@ -468,6 +505,8 @@ const struct cfg802154_ops mac802154_config_ops = {
>         .set_max_frame_retries = ieee802154_set_max_frame_retries,
>         .set_lbt_mode = ieee802154_set_lbt_mode,
>         .set_ackreq_default = ieee802154_set_ackreq_default,
> +       .trigger_scan = mac802154_trigger_scan,
> +       .abort_scan = mac802154_abort_scan,
>  #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
>         .get_llsec_table = ieee802154_get_llsec_table,
>         .lock_llsec_table = ieee802154_lock_llsec_table,
> diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h
> index b8775bcc9003..46394e2e0486 100644
> --- a/net/mac802154/ieee802154_i.h
> +++ b/net/mac802154/ieee802154_i.h
> @@ -21,6 +21,10 @@
>
>  #include "llsec.h"
>
> +enum ieee802154_ongoing {
> +       IEEE802154_IS_SCANNING = BIT(0),
> +};
> +
>  /* mac802154 device private data */
>  struct ieee802154_local {
>         struct ieee802154_hw hw;
> @@ -50,8 +54,19 @@ struct ieee802154_local {
>
>         struct hrtimer ifs_timer;
>
> +       /* Scanning */
> +       struct mutex scan_lock;
> +       int scan_channel_idx;
> +       struct cfg802154_scan_request __rcu *scan_req;
> +       struct delayed_work scan_work;
> +
> +       /* Asynchronous tasks */
> +       struct list_head rx_beacon_list;
> +       struct work_struct rx_beacon_work;
> +
>         bool started;
>         bool suspended;
> +       unsigned long ongoing;
>
>         struct tasklet_struct tasklet;
>         struct sk_buff_head skb_queue;
> @@ -210,6 +225,20 @@ void mac802154_unlock_table(struct net_device *dev);
>
>  int mac802154_wpan_update_llsec(struct net_device *dev);
>
> +/* PAN management handling */
> +void mac802154_scan_worker(struct work_struct *work);
> +int mac802154_trigger_scan_locked(struct ieee802154_sub_if_data *sdata,
> +                                 struct cfg802154_scan_request *request);
> +int mac802154_abort_scan_locked(struct ieee802154_local *local);
> +int mac802154_process_beacon(struct ieee802154_local *local,
> +                            struct sk_buff *skb);
> +void mac802154_rx_beacon_worker(struct work_struct *work);
> +
> +static inline bool mac802154_is_scanning(struct ieee802154_local *local)
> +{
> +       return test_bit(IEEE802154_IS_SCANNING, &local->ongoing);
> +}
> +
>  /* interface handling */
>  int ieee802154_iface_init(void);
>  void ieee802154_iface_exit(void);
> diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
> index 7715e17d9ba1..431cc544dbf2 100644
> --- a/net/mac802154/iface.c
> +++ b/net/mac802154/iface.c
> @@ -315,6 +315,12 @@ static int mac802154_slave_close(struct net_device *dev)
>
>         ASSERT_RTNL();
>
> +       if (mac802154_is_scanning(local)) {
> +               mutex_lock(&local->scan_lock);
> +               mac802154_abort_scan_locked(local);
> +               mutex_unlock(&local->scan_lock);
> +       }
> +
>         mutex_lock(&local->device_lock);
>
>         netif_stop_queue(dev);
> diff --git a/net/mac802154/main.c b/net/mac802154/main.c
> index e5fb7ed73663..604fbc5b07df 100644
> --- a/net/mac802154/main.c
> +++ b/net/mac802154/main.c
> @@ -89,14 +89,18 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
>         local->ops = ops;
>
>         INIT_LIST_HEAD(&local->interfaces);
> +       INIT_LIST_HEAD(&local->rx_beacon_list);
>         mutex_init(&local->iflist_mtx);
>         mutex_init(&local->device_lock);
> +       mutex_init(&local->scan_lock);
>
>         tasklet_setup(&local->tasklet, ieee802154_tasklet_handler);
>
>         skb_queue_head_init(&local->skb_queue);
>
>         INIT_WORK(&local->sync_tx_work, ieee802154_xmit_sync_worker);
> +       INIT_DELAYED_WORK(&local->scan_work, mac802154_scan_worker);
> +       INIT_WORK(&local->rx_beacon_work, mac802154_rx_beacon_worker);
>
>         /* init supported flags with 802.15.4 default ranges */
>         phy->supported.max_minbe = 8;
> diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
> index 39459d8d787a..0b1cf8c85ee9 100644
> --- a/net/mac802154/rx.c
> +++ b/net/mac802154/rx.c
> @@ -29,11 +29,36 @@ static int ieee802154_deliver_skb(struct sk_buff *skb)
>         return netif_receive_skb(skb);
>  }
>
> +void mac802154_rx_beacon_worker(struct work_struct *work)
> +{
> +       struct ieee802154_local *local =
> +               container_of(work, struct ieee802154_local, rx_beacon_work);
> +       struct cfg802154_mac_pkt *mac_pkt;
> +
> +       mutex_lock(&local->scan_lock);
> +
> +       if (list_empty(&local->rx_beacon_list))
> +               goto unlock;
> +
> +       mac_pkt = list_first_entry(&local->rx_beacon_list,
> +                                  struct cfg802154_mac_pkt, node);
> +
> +       mac802154_process_beacon(local, mac_pkt->skb);
> +
> +       list_del(&mac_pkt->node);
> +       kfree_skb(mac_pkt->skb);
> +       kfree(mac_pkt);
> +
> +unlock:
> +       mutex_unlock(&local->scan_lock);
> +}
> +
>  static int
>  ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata,
>                        struct sk_buff *skb, const struct ieee802154_hdr *hdr)
>  {
>         struct wpan_dev *wpan_dev = &sdata->wpan_dev;
> +       struct cfg802154_mac_pkt *mac_pkt;
>         __le16 span, sshort;
>         int rc;
>
> @@ -94,6 +119,18 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata,
>
>         switch (mac_cb(skb)->type) {
>         case IEEE802154_FC_TYPE_BEACON:
> +               if (!mac802154_is_scanning(sdata->local))
> +                       goto fail;
> +
> +               mac_pkt = kzalloc(sizeof(*mac_pkt), GFP_ATOMIC);
> +               if (!mac_pkt)
> +                       goto fail;
> +
> +               mac_pkt->skb = skb_get(skb);
> +               mac_pkt->sdata = sdata;
> +               list_add_tail(&mac_pkt->node, &sdata->local->rx_beacon_list);
> +               queue_work(sdata->local->workqueue, &sdata->local->rx_beacon_work);
> +               goto success;
>         case IEEE802154_FC_TYPE_ACK:
>         case IEEE802154_FC_TYPE_MAC_CMD:
>                 goto fail;
> @@ -109,6 +146,10 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata,
>  fail:
>         kfree_skb(skb);
>         return NET_RX_DROP;
> +
> +success:
> +       kfree_skb(skb);
> +       return NET_RX_SUCCESS;
>  }
>
>  static void
> @@ -268,10 +309,12 @@ void ieee802154_rx(struct ieee802154_local *local, struct sk_buff *skb)
>
>         ieee802154_monitors_rx(local, skb);
>
> -       /* Check if transceiver doesn't validate the checksum.
> -        * If not we validate the checksum here.
> +       /* Check if the transceiver doesn't validate the checksum, or if the
> +        * check might have been disabled like during a scan. In these cases,
> +        * we validate the checksum here.
>          */
> -       if (local->hw.flags & IEEE802154_HW_RX_DROP_BAD_CKSUM) {
> +       if (local->hw.flags & IEEE802154_HW_RX_DROP_BAD_CKSUM ||
> +           mac802154_is_scanning(local)) {
>                 crc = crc_ccitt(0, skb->data, skb->len);
>                 if (crc) {
>                         rcu_read_unlock();
> diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c
> new file mode 100644
> index 000000000000..c74f6c3baa95
> --- /dev/null
> +++ b/net/mac802154/scan.c
> @@ -0,0 +1,264 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * IEEE 802.15.4 scanning management
> + *
> + * Copyright (C) Qorvo, 2021
> + * Authors:
> + *   - David Girault <david.girault@qorvo.com>
> + *   - Miquel Raynal <miquel.raynal@bootlin.com>
> + */
> +
> +#include <linux/module.h>
> +#include <linux/rtnetlink.h>
> +#include <net/mac802154.h>
> +
> +#include "ieee802154_i.h"
> +#include "driver-ops.h"
> +#include "../ieee802154/nl802154.h"
> +
> +static bool mac802154_check_promiscuous(struct ieee802154_local *local)
> +{
> +       struct ieee802154_sub_if_data *sdata;
> +       bool promiscuous_on = false;
> +
> +       /* Check if one subif is already in promiscuous mode. Since the list is
> +        * protected by its own mutex, take it here to ensure no modification
> +        * occurs during the check.
> +        */
> +       rcu_read_lock();
> +       list_for_each_entry(sdata, &local->interfaces, list) {
> +               if (ieee802154_sdata_running(sdata) &&
> +                   sdata->wpan_dev.promiscuous_mode) {
> +                       /* At least one is in promiscuous mode */
> +                       promiscuous_on = true;
> +                       break;
> +               }
> +       }
> +       rcu_read_unlock();
> +
> +       return promiscuous_on;
> +}
> +
> +static int mac802154_set_promiscuous_mode(struct ieee802154_local *local,
> +                                         bool state)
> +{
> +       bool promiscuous_on = mac802154_check_promiscuous(local);
> +       int ret;
> +
> +       if ((state && promiscuous_on) || (!state && !promiscuous_on))
> +               return 0;
> +
> +       ret = drv_set_promiscuous_mode(local, state);
> +       if (ret)
> +               pr_err("Failed to %s promiscuous mode for SW scanning",
> +                      state ? "set" : "reset");
> +
> +       return ret;
> +}
> +
> +static int mac802154_send_scan_done(struct ieee802154_local *local)
> +{
> +       struct cfg802154_scan_request *scan_req;
> +       struct wpan_phy *wpan_phy;
> +       struct wpan_dev *wpan_dev;
> +
> +       scan_req = rcu_dereference_protected(local->scan_req,
> +                                            lockdep_is_held(&local->scan_lock));
> +       wpan_phy = scan_req->wpan_phy;
> +       wpan_dev = scan_req->wpan_dev;
> +
> +       cfg802154_flush_known_coordinators(wpan_dev);
> +
> +       return nl802154_send_scan_done(wpan_phy, wpan_dev, scan_req);
> +}
> +
> +static int mac802154_end_of_scan(struct ieee802154_local *local)
> +{
> +       drv_set_channel(local, local->phy->current_page,
> +                       local->phy->current_channel);
> +       ieee802154_configure_durations(local->phy, local->phy->current_page,
> +                                      local->phy->current_channel);
> +       clear_bit(IEEE802154_IS_SCANNING, &local->ongoing);
> +       mac802154_set_promiscuous_mode(local, false);
> +       ieee802154_mlme_op_post(local);
> +       module_put(local->hw.parent->driver->owner);
> +
> +       return mac802154_send_scan_done(local);
> +}
> +
> +int mac802154_abort_scan_locked(struct ieee802154_local *local)
> +{
> +       lockdep_assert_held(&local->scan_lock);
> +
> +       if (!mac802154_is_scanning(local))
> +               return -ESRCH;
> +
> +       cancel_delayed_work(&local->scan_work);
> +
> +       return mac802154_end_of_scan(local);
> +}
> +
> +static unsigned int mac802154_scan_get_channel_time(u8 duration_order,
> +                                                   u8 symbol_duration)
> +{
> +       u64 base_super_frame_duration = (u64)symbol_duration *
> +               IEEE802154_SUPERFRAME_PERIOD * IEEE802154_SLOT_PERIOD;
> +
> +       return usecs_to_jiffies(base_super_frame_duration *
> +                               (BIT(duration_order) + 1));
> +}
> +
> +void mac802154_flush_queued_beacons(struct ieee802154_local *local)
> +{
> +       struct cfg802154_mac_pkt *beacon, *tmp;
> +
> +       lockdep_assert_held(&local->scan_lock);
> +
> +       list_for_each_entry_safe(beacon, tmp, &local->rx_beacon_list, node) {
> +               list_del(&beacon->node);
> +               kfree_skb(beacon->skb);
> +               kfree(beacon);
> +       }
> +}
> +
> +void mac802154_scan_worker(struct work_struct *work)
> +{
> +       struct ieee802154_local *local =
> +               container_of(work, struct ieee802154_local, scan_work.work);
> +       struct cfg802154_scan_request *scan_req;
> +       struct ieee802154_sub_if_data *sdata;
> +       unsigned int scan_duration;
> +       unsigned long chan;
> +       int ret;
> +
> +       mutex_lock(&local->scan_lock);
> +
> +       if (!mac802154_is_scanning(local))
> +               goto unlock_mutex;
> +
> +       scan_req = rcu_dereference_protected(local->scan_req,
> +                                            lockdep_is_held(&local->scan_lock));
> +       sdata = IEEE802154_WPAN_DEV_TO_SUB_IF(scan_req->wpan_dev);
> +
> +       if (local->suspended || !ieee802154_sdata_running(sdata))
> +               goto queue_work;
> +
> +       do {
> +               chan = find_next_bit((const unsigned long *)&scan_req->channels,
> +                                    IEEE802154_MAX_CHANNEL + 1,
> +                                    local->scan_channel_idx + 1);
> +
> +               /* If there are no more channels left, complete the scan */
> +               if (chan > IEEE802154_MAX_CHANNEL) {
> +                       mac802154_end_of_scan(local);
> +                       goto unlock_mutex;
> +               }
> +
> +               /* Bypass the stack on purpose. As the channel change cannot be
> +                * made atomic with regard to the incoming beacon flow, we flush
> +                * the beacons list after changing the channel and before
> +                * releasing the scan lock, to avoid processing beacons which
> +                * have been received during this time frame.
> +                */
> +               ret = drv_set_channel(local, scan_req->page, chan);
> +               local->scan_channel_idx = chan;
> +               ieee802154_configure_durations(local->phy, scan_req->page, chan);
> +               mac802154_flush_queued_beacons(local);
> +       } while (ret);
> +
> +queue_work:
> +       scan_duration = mac802154_scan_get_channel_time(scan_req->duration,
> +                                                       local->phy->symbol_duration);
> +       pr_debug("Scan channel %lu of page %u for %ums\n",
> +                chan, scan_req->page, jiffies_to_msecs(scan_duration));
> +       queue_delayed_work(local->workqueue, &local->scan_work, scan_duration);
> +
> +unlock_mutex:
> +       mutex_unlock(&local->scan_lock);
> +}
> +
> +int mac802154_trigger_scan_locked(struct ieee802154_sub_if_data *sdata,
> +                                 struct cfg802154_scan_request *request)
> +{
> +       struct ieee802154_local *local = sdata->local;
> +       int ret;
> +
> +       lockdep_assert_held(&local->scan_lock);
> +
> +       if (mac802154_is_scanning(local))
> +               return -EBUSY;
> +
> +       /* TODO: support other scanning type */
> +       if (request->type != NL802154_SCAN_PASSIVE)
> +               return -EOPNOTSUPP;
> +
> +       /* Store scanning parameters */
> +       rcu_assign_pointer(local->scan_req, request);
> +
> +       /* Software scanning requires to set promiscuous mode, so we need to
> +        * pause the Tx queue during the entire operation.
> +        */
> +       ieee802154_mlme_op_pre(local);
> +
> +       ret = mac802154_set_promiscuous_mode(local, true);
> +       if (ret)
> +               goto cancel_mlme;

I know some driver datasheets and as I said before, it's not allowed
to set promiscuous mode while in receive mode. We need to stop tx,
what we are doing. Then call stop() driver callback,
synchronize_net(), mac802154_set_promiscuous_mode(...), start(). The
same always for the opposite.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 10/20] net: mac802154: Handle passive scanning
  2022-07-15  3:33   ` Alexander Aring
@ 2022-07-15  3:42     ` Alexander Aring
  2022-08-19 17:22       ` Miquel Raynal
  2022-08-01 23:42     ` Alexander Aring
  1 sibling, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-07-15  3:42 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Thu, Jul 14, 2022 at 11:33 PM Alexander Aring <aahringo@redhat.com> wrote:
>
> Hi,
>
> On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> >
> > Implement the core hooks in order to provide the softMAC layer support
> > for passive scans. Scans are requested by the user and can be aborted.
> >
> > Changing the channels is prohibited during the scan.
> >
> > As transceivers enter promiscuous mode during scans, they might stop
> > checking frame validity so we ensure this gets done at mac level.
> >
> > The implementation uses a workqueue triggered at a certain interval
> > depending on the symbol duration for the current channel and the
> > duration order provided.
> >
> > Received beacons during a passive scan are processed also in a work
> > queue and forwarded to the upper layer.
> >
> > Active scanning is not supported yet.
> >
> > Co-developed-by: David Girault <david.girault@qorvo.com>
> > Signed-off-by: David Girault <david.girault@qorvo.com>
> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > ---
> >  include/linux/ieee802154.h   |   4 +
> >  include/net/cfg802154.h      |  12 ++
> >  net/mac802154/Makefile       |   2 +-
> >  net/mac802154/cfg.c          |  39 ++++++
> >  net/mac802154/ieee802154_i.h |  29 ++++
> >  net/mac802154/iface.c        |   6 +
> >  net/mac802154/main.c         |   4 +
> >  net/mac802154/rx.c           |  49 ++++++-
> >  net/mac802154/scan.c         | 264 +++++++++++++++++++++++++++++++++++
> >  9 files changed, 405 insertions(+), 4 deletions(-)
> >  create mode 100644 net/mac802154/scan.c
> >
> > diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h
> > index 929d4e672575..94bfee22bd0a 100644
> > --- a/include/linux/ieee802154.h
> > +++ b/include/linux/ieee802154.h
> > @@ -47,6 +47,10 @@
> >  /* Duration in superframe order */
> >  #define IEEE802154_MAX_SCAN_DURATION   14
> >  #define IEEE802154_ACTIVE_SCAN_DURATION        15
> > +/* Superframe duration in slots */
> > +#define IEEE802154_SUPERFRAME_PERIOD   16
> > +/* Various periods expressed in symbols */
> > +#define IEEE802154_SLOT_PERIOD         60
> >  #define IEEE802154_LIFS_PERIOD         40
> >  #define IEEE802154_SIFS_PERIOD         12
> >  #define IEEE802154_MAX_SIFS_FRAME_SIZE 18
> > diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
> > index f05ce3c45b5d..206283fd4b72 100644
> > --- a/include/net/cfg802154.h
> > +++ b/include/net/cfg802154.h
> > @@ -300,6 +300,18 @@ struct cfg802154_scan_request {
> >         struct wpan_phy *wpan_phy;
> >  };
> >
> > +/**
> > + * struct cfg802154_mac_pkt - MAC packet descriptor (beacon/command)
> > + * @node: MAC packets to process list member
> > + * @skb: the received sk_buff
> > + * @sdata: the interface on which @skb was received
> > + */
> > +struct cfg802154_mac_pkt {
> > +       struct list_head node;
> > +       struct sk_buff *skb;
> > +       struct ieee802154_sub_if_data *sdata;
> > +};
> > +
> >  struct ieee802154_llsec_key_id {
> >         u8 mode;
> >         u8 id;
> > diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile
> > index 4059295fdbf8..43d1347b37ee 100644
> > --- a/net/mac802154/Makefile
> > +++ b/net/mac802154/Makefile
> > @@ -1,6 +1,6 @@
> >  # SPDX-License-Identifier: GPL-2.0-only
> >  obj-$(CONFIG_MAC802154)        += mac802154.o
> >  mac802154-objs         := main.o rx.o tx.o mac_cmd.o mib.o \
> > -                          iface.o llsec.o util.o cfg.o trace.o
> > +                          iface.o llsec.o util.o cfg.o scan.o trace.o
> >
> >  CFLAGS_trace.o := -I$(src)
> > diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c
> > index 4116a894c86e..1f532d93d870 100644
> > --- a/net/mac802154/cfg.c
> > +++ b/net/mac802154/cfg.c
> > @@ -114,6 +114,10 @@ ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel)
> >             wpan_phy->current_channel == channel)
> >                 return 0;
> >
> > +       /* Refuse to change channels during a scanning operation */
> > +       if (mac802154_is_scanning(local))
> > +               return -EBUSY;
> > +
>
> okay, that answered one of my other questions in another mail.
>
> >         ret = drv_set_channel(local, page, channel);
> >         if (!ret) {
> >                 wpan_phy->current_page = page;
> > @@ -261,6 +265,39 @@ ieee802154_set_ackreq_default(struct wpan_phy *wpan_phy,
> >         return 0;
> >  }
> >
> > +static int mac802154_trigger_scan(struct wpan_phy *wpan_phy,
> > +                                 struct cfg802154_scan_request *request)
> > +{
> > +       struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
> > +       struct ieee802154_sub_if_data *sdata;
> > +       int ret;
> > +
> > +       sdata = IEEE802154_WPAN_DEV_TO_SUB_IF(request->wpan_dev);
> > +
> > +       ASSERT_RTNL();
> > +
> > +       mutex_lock(&local->scan_lock);
> > +       ret = mac802154_trigger_scan_locked(sdata, request);
> > +       mutex_unlock(&local->scan_lock);
> > +
> > +       return ret;
> > +}
> > +
> > +static int mac802154_abort_scan(struct wpan_phy *wpan_phy,
> > +                               struct wpan_dev *wpan_dev)
> > +{
> > +       struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
> > +       int ret;
> > +
> > +       ASSERT_RTNL();
> > +
> > +       mutex_lock(&local->scan_lock);
> > +       ret = mac802154_abort_scan_locked(local);
> > +       mutex_unlock(&local->scan_lock);
> > +
> > +       return ret;
> > +}
> > +
> >  #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
> >  static void
> >  ieee802154_get_llsec_table(struct wpan_phy *wpan_phy,
> > @@ -468,6 +505,8 @@ const struct cfg802154_ops mac802154_config_ops = {
> >         .set_max_frame_retries = ieee802154_set_max_frame_retries,
> >         .set_lbt_mode = ieee802154_set_lbt_mode,
> >         .set_ackreq_default = ieee802154_set_ackreq_default,
> > +       .trigger_scan = mac802154_trigger_scan,
> > +       .abort_scan = mac802154_abort_scan,
> >  #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
> >         .get_llsec_table = ieee802154_get_llsec_table,
> >         .lock_llsec_table = ieee802154_lock_llsec_table,
> > diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h
> > index b8775bcc9003..46394e2e0486 100644
> > --- a/net/mac802154/ieee802154_i.h
> > +++ b/net/mac802154/ieee802154_i.h
> > @@ -21,6 +21,10 @@
> >
> >  #include "llsec.h"
> >
> > +enum ieee802154_ongoing {
> > +       IEEE802154_IS_SCANNING = BIT(0),
> > +};
> > +
> >  /* mac802154 device private data */
> >  struct ieee802154_local {
> >         struct ieee802154_hw hw;
> > @@ -50,8 +54,19 @@ struct ieee802154_local {
> >
> >         struct hrtimer ifs_timer;
> >
> > +       /* Scanning */
> > +       struct mutex scan_lock;
> > +       int scan_channel_idx;
> > +       struct cfg802154_scan_request __rcu *scan_req;
> > +       struct delayed_work scan_work;
> > +
> > +       /* Asynchronous tasks */
> > +       struct list_head rx_beacon_list;
> > +       struct work_struct rx_beacon_work;
> > +
> >         bool started;
> >         bool suspended;
> > +       unsigned long ongoing;
> >
> >         struct tasklet_struct tasklet;
> >         struct sk_buff_head skb_queue;
> > @@ -210,6 +225,20 @@ void mac802154_unlock_table(struct net_device *dev);
> >
> >  int mac802154_wpan_update_llsec(struct net_device *dev);
> >
> > +/* PAN management handling */
> > +void mac802154_scan_worker(struct work_struct *work);
> > +int mac802154_trigger_scan_locked(struct ieee802154_sub_if_data *sdata,
> > +                                 struct cfg802154_scan_request *request);
> > +int mac802154_abort_scan_locked(struct ieee802154_local *local);
> > +int mac802154_process_beacon(struct ieee802154_local *local,
> > +                            struct sk_buff *skb);
> > +void mac802154_rx_beacon_worker(struct work_struct *work);
> > +
> > +static inline bool mac802154_is_scanning(struct ieee802154_local *local)
> > +{
> > +       return test_bit(IEEE802154_IS_SCANNING, &local->ongoing);
> > +}
> > +
> >  /* interface handling */
> >  int ieee802154_iface_init(void);
> >  void ieee802154_iface_exit(void);
> > diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
> > index 7715e17d9ba1..431cc544dbf2 100644
> > --- a/net/mac802154/iface.c
> > +++ b/net/mac802154/iface.c
> > @@ -315,6 +315,12 @@ static int mac802154_slave_close(struct net_device *dev)
> >
> >         ASSERT_RTNL();
> >
> > +       if (mac802154_is_scanning(local)) {
> > +               mutex_lock(&local->scan_lock);
> > +               mac802154_abort_scan_locked(local);
> > +               mutex_unlock(&local->scan_lock);
> > +       }
> > +
> >         mutex_lock(&local->device_lock);
> >
> >         netif_stop_queue(dev);
> > diff --git a/net/mac802154/main.c b/net/mac802154/main.c
> > index e5fb7ed73663..604fbc5b07df 100644
> > --- a/net/mac802154/main.c
> > +++ b/net/mac802154/main.c
> > @@ -89,14 +89,18 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
> >         local->ops = ops;
> >
> >         INIT_LIST_HEAD(&local->interfaces);
> > +       INIT_LIST_HEAD(&local->rx_beacon_list);
> >         mutex_init(&local->iflist_mtx);
> >         mutex_init(&local->device_lock);
> > +       mutex_init(&local->scan_lock);
> >
> >         tasklet_setup(&local->tasklet, ieee802154_tasklet_handler);
> >
> >         skb_queue_head_init(&local->skb_queue);
> >
> >         INIT_WORK(&local->sync_tx_work, ieee802154_xmit_sync_worker);
> > +       INIT_DELAYED_WORK(&local->scan_work, mac802154_scan_worker);
> > +       INIT_WORK(&local->rx_beacon_work, mac802154_rx_beacon_worker);
> >
> >         /* init supported flags with 802.15.4 default ranges */
> >         phy->supported.max_minbe = 8;
> > diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
> > index 39459d8d787a..0b1cf8c85ee9 100644
> > --- a/net/mac802154/rx.c
> > +++ b/net/mac802154/rx.c
> > @@ -29,11 +29,36 @@ static int ieee802154_deliver_skb(struct sk_buff *skb)
> >         return netif_receive_skb(skb);
> >  }
> >
> > +void mac802154_rx_beacon_worker(struct work_struct *work)
> > +{
> > +       struct ieee802154_local *local =
> > +               container_of(work, struct ieee802154_local, rx_beacon_work);
> > +       struct cfg802154_mac_pkt *mac_pkt;
> > +
> > +       mutex_lock(&local->scan_lock);
> > +
> > +       if (list_empty(&local->rx_beacon_list))
> > +               goto unlock;
> > +
> > +       mac_pkt = list_first_entry(&local->rx_beacon_list,
> > +                                  struct cfg802154_mac_pkt, node);
> > +
> > +       mac802154_process_beacon(local, mac_pkt->skb);
> > +
> > +       list_del(&mac_pkt->node);
> > +       kfree_skb(mac_pkt->skb);
> > +       kfree(mac_pkt);
> > +
> > +unlock:
> > +       mutex_unlock(&local->scan_lock);
> > +}
> > +
> >  static int
> >  ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata,
> >                        struct sk_buff *skb, const struct ieee802154_hdr *hdr)
> >  {
> >         struct wpan_dev *wpan_dev = &sdata->wpan_dev;
> > +       struct cfg802154_mac_pkt *mac_pkt;
> >         __le16 span, sshort;
> >         int rc;
> >
> > @@ -94,6 +119,18 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata,
> >
> >         switch (mac_cb(skb)->type) {
> >         case IEEE802154_FC_TYPE_BEACON:
> > +               if (!mac802154_is_scanning(sdata->local))
> > +                       goto fail;
> > +
> > +               mac_pkt = kzalloc(sizeof(*mac_pkt), GFP_ATOMIC);
> > +               if (!mac_pkt)
> > +                       goto fail;
> > +
> > +               mac_pkt->skb = skb_get(skb);
> > +               mac_pkt->sdata = sdata;
> > +               list_add_tail(&mac_pkt->node, &sdata->local->rx_beacon_list);
> > +               queue_work(sdata->local->workqueue, &sdata->local->rx_beacon_work);
> > +               goto success;
> >         case IEEE802154_FC_TYPE_ACK:
> >         case IEEE802154_FC_TYPE_MAC_CMD:
> >                 goto fail;
> > @@ -109,6 +146,10 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata,
> >  fail:
> >         kfree_skb(skb);
> >         return NET_RX_DROP;
> > +
> > +success:
> > +       kfree_skb(skb);
> > +       return NET_RX_SUCCESS;
> >  }
> >
> >  static void
> > @@ -268,10 +309,12 @@ void ieee802154_rx(struct ieee802154_local *local, struct sk_buff *skb)
> >
> >         ieee802154_monitors_rx(local, skb);
> >
> > -       /* Check if transceiver doesn't validate the checksum.
> > -        * If not we validate the checksum here.
> > +       /* Check if the transceiver doesn't validate the checksum, or if the
> > +        * check might have been disabled like during a scan. In these cases,
> > +        * we validate the checksum here.
> >          */
> > -       if (local->hw.flags & IEEE802154_HW_RX_DROP_BAD_CKSUM) {
> > +       if (local->hw.flags & IEEE802154_HW_RX_DROP_BAD_CKSUM ||
> > +           mac802154_is_scanning(local)) {
> >                 crc = crc_ccitt(0, skb->data, skb->len);
> >                 if (crc) {
> >                         rcu_read_unlock();
> > diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c
> > new file mode 100644
> > index 000000000000..c74f6c3baa95
> > --- /dev/null
> > +++ b/net/mac802154/scan.c
> > @@ -0,0 +1,264 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * IEEE 802.15.4 scanning management
> > + *
> > + * Copyright (C) Qorvo, 2021
> > + * Authors:
> > + *   - David Girault <david.girault@qorvo.com>
> > + *   - Miquel Raynal <miquel.raynal@bootlin.com>
> > + */
> > +
> > +#include <linux/module.h>
> > +#include <linux/rtnetlink.h>
> > +#include <net/mac802154.h>
> > +
> > +#include "ieee802154_i.h"
> > +#include "driver-ops.h"
> > +#include "../ieee802154/nl802154.h"
> > +
> > +static bool mac802154_check_promiscuous(struct ieee802154_local *local)
> > +{
> > +       struct ieee802154_sub_if_data *sdata;
> > +       bool promiscuous_on = false;
> > +
> > +       /* Check if one subif is already in promiscuous mode. Since the list is
> > +        * protected by its own mutex, take it here to ensure no modification
> > +        * occurs during the check.
> > +        */
> > +       rcu_read_lock();
> > +       list_for_each_entry(sdata, &local->interfaces, list) {
> > +               if (ieee802154_sdata_running(sdata) &&
> > +                   sdata->wpan_dev.promiscuous_mode) {
> > +                       /* At least one is in promiscuous mode */
> > +                       promiscuous_on = true;
> > +                       break;
> > +               }
> > +       }
> > +       rcu_read_unlock();
> > +
> > +       return promiscuous_on;
> > +}
> > +
> > +static int mac802154_set_promiscuous_mode(struct ieee802154_local *local,
> > +                                         bool state)
> > +{
> > +       bool promiscuous_on = mac802154_check_promiscuous(local);
> > +       int ret;
> > +
> > +       if ((state && promiscuous_on) || (!state && !promiscuous_on))
> > +               return 0;
> > +
> > +       ret = drv_set_promiscuous_mode(local, state);
> > +       if (ret)
> > +               pr_err("Failed to %s promiscuous mode for SW scanning",
> > +                      state ? "set" : "reset");
> > +
> > +       return ret;
> > +}
> > +
> > +static int mac802154_send_scan_done(struct ieee802154_local *local)
> > +{
> > +       struct cfg802154_scan_request *scan_req;
> > +       struct wpan_phy *wpan_phy;
> > +       struct wpan_dev *wpan_dev;
> > +
> > +       scan_req = rcu_dereference_protected(local->scan_req,
> > +                                            lockdep_is_held(&local->scan_lock));
> > +       wpan_phy = scan_req->wpan_phy;
> > +       wpan_dev = scan_req->wpan_dev;
> > +
> > +       cfg802154_flush_known_coordinators(wpan_dev);
> > +
> > +       return nl802154_send_scan_done(wpan_phy, wpan_dev, scan_req);
> > +}
> > +
> > +static int mac802154_end_of_scan(struct ieee802154_local *local)
> > +{
> > +       drv_set_channel(local, local->phy->current_page,
> > +                       local->phy->current_channel);
> > +       ieee802154_configure_durations(local->phy, local->phy->current_page,
> > +                                      local->phy->current_channel);
> > +       clear_bit(IEEE802154_IS_SCANNING, &local->ongoing);
> > +       mac802154_set_promiscuous_mode(local, false);
> > +       ieee802154_mlme_op_post(local);
> > +       module_put(local->hw.parent->driver->owner);
> > +
> > +       return mac802154_send_scan_done(local);
> > +}
> > +
> > +int mac802154_abort_scan_locked(struct ieee802154_local *local)
> > +{
> > +       lockdep_assert_held(&local->scan_lock);
> > +
> > +       if (!mac802154_is_scanning(local))
> > +               return -ESRCH;
> > +
> > +       cancel_delayed_work(&local->scan_work);
> > +
> > +       return mac802154_end_of_scan(local);
> > +}
> > +
> > +static unsigned int mac802154_scan_get_channel_time(u8 duration_order,
> > +                                                   u8 symbol_duration)
> > +{
> > +       u64 base_super_frame_duration = (u64)symbol_duration *
> > +               IEEE802154_SUPERFRAME_PERIOD * IEEE802154_SLOT_PERIOD;
> > +
> > +       return usecs_to_jiffies(base_super_frame_duration *
> > +                               (BIT(duration_order) + 1));
> > +}
> > +
> > +void mac802154_flush_queued_beacons(struct ieee802154_local *local)
> > +{
> > +       struct cfg802154_mac_pkt *beacon, *tmp;
> > +
> > +       lockdep_assert_held(&local->scan_lock);
> > +
> > +       list_for_each_entry_safe(beacon, tmp, &local->rx_beacon_list, node) {
> > +               list_del(&beacon->node);
> > +               kfree_skb(beacon->skb);
> > +               kfree(beacon);
> > +       }
> > +}
> > +
> > +void mac802154_scan_worker(struct work_struct *work)
> > +{
> > +       struct ieee802154_local *local =
> > +               container_of(work, struct ieee802154_local, scan_work.work);
> > +       struct cfg802154_scan_request *scan_req;
> > +       struct ieee802154_sub_if_data *sdata;
> > +       unsigned int scan_duration;
> > +       unsigned long chan;
> > +       int ret;
> > +
> > +       mutex_lock(&local->scan_lock);
> > +
> > +       if (!mac802154_is_scanning(local))
> > +               goto unlock_mutex;
> > +
> > +       scan_req = rcu_dereference_protected(local->scan_req,
> > +                                            lockdep_is_held(&local->scan_lock));
> > +       sdata = IEEE802154_WPAN_DEV_TO_SUB_IF(scan_req->wpan_dev);
> > +
> > +       if (local->suspended || !ieee802154_sdata_running(sdata))
> > +               goto queue_work;
> > +
> > +       do {
> > +               chan = find_next_bit((const unsigned long *)&scan_req->channels,
> > +                                    IEEE802154_MAX_CHANNEL + 1,
> > +                                    local->scan_channel_idx + 1);
> > +
> > +               /* If there are no more channels left, complete the scan */
> > +               if (chan > IEEE802154_MAX_CHANNEL) {
> > +                       mac802154_end_of_scan(local);
> > +                       goto unlock_mutex;
> > +               }
> > +
> > +               /* Bypass the stack on purpose. As the channel change cannot be
> > +                * made atomic with regard to the incoming beacon flow, we flush
> > +                * the beacons list after changing the channel and before
> > +                * releasing the scan lock, to avoid processing beacons which
> > +                * have been received during this time frame.
> > +                */
> > +               ret = drv_set_channel(local, scan_req->page, chan);
> > +               local->scan_channel_idx = chan;
> > +               ieee802154_configure_durations(local->phy, scan_req->page, chan);
> > +               mac802154_flush_queued_beacons(local);
> > +       } while (ret);
> > +
> > +queue_work:
> > +       scan_duration = mac802154_scan_get_channel_time(scan_req->duration,
> > +                                                       local->phy->symbol_duration);
> > +       pr_debug("Scan channel %lu of page %u for %ums\n",
> > +                chan, scan_req->page, jiffies_to_msecs(scan_duration));
> > +       queue_delayed_work(local->workqueue, &local->scan_work, scan_duration);
> > +
> > +unlock_mutex:
> > +       mutex_unlock(&local->scan_lock);
> > +}
> > +
> > +int mac802154_trigger_scan_locked(struct ieee802154_sub_if_data *sdata,
> > +                                 struct cfg802154_scan_request *request)
> > +{
> > +       struct ieee802154_local *local = sdata->local;
> > +       int ret;
> > +
> > +       lockdep_assert_held(&local->scan_lock);
> > +
> > +       if (mac802154_is_scanning(local))
> > +               return -EBUSY;
> > +
> > +       /* TODO: support other scanning type */
> > +       if (request->type != NL802154_SCAN_PASSIVE)
> > +               return -EOPNOTSUPP;
> > +
> > +       /* Store scanning parameters */
> > +       rcu_assign_pointer(local->scan_req, request);
> > +
> > +       /* Software scanning requires to set promiscuous mode, so we need to
> > +        * pause the Tx queue during the entire operation.
> > +        */
> > +       ieee802154_mlme_op_pre(local);
> > +
> > +       ret = mac802154_set_promiscuous_mode(local, true);
> > +       if (ret)
> > +               goto cancel_mlme;
>
> I know some driver datasheets and as I said before, it's not allowed
> to set promiscuous mode while in receive mode. We need to stop tx,
> what we are doing. Then call stop() driver callback,
> synchronize_net(), mac802154_set_promiscuous_mode(...), start(). The
> same always for the opposite.

s/always/as well/

I need to say, it needs to be something like that... we need to be
careful here e.g. lots of monitor interfaces on one phy which has
currently a serious use case for hwsim.

We also don't need to do anything above if we already are in
promiscuous mode, which might be worth checking.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 10/20] net: mac802154: Handle passive scanning
  2022-07-15  3:33   ` Alexander Aring
  2022-07-15  3:42     ` Alexander Aring
@ 2022-08-01 23:42     ` Alexander Aring
  2022-08-01 23:54       ` Alexander Aring
  1 sibling, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-08-01 23:42 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Thu, Jul 14, 2022 at 11:33 PM Alexander Aring <aahringo@redhat.com> wrote:
...
>
> I know some driver datasheets and as I said before, it's not allowed
> to set promiscuous mode while in receive mode. We need to stop tx,
> what we are doing. Then call stop() driver callback,
> synchronize_net(), mac802154_set_promiscuous_mode(...), start(). The
> same always for the opposite.
>

I think we should try to work on that as a next patch series to offer
such functionality in which "filtering level" the hardware should be
"started". As I said it cannot be changed during runtime as
"transceiver is being in receive mode" but there is the possibility to
stop/start the hardware _transparent_ from the user to change the
"filtering level". I say filtering level because I think this is what
the standard uses as a term. The one which is needed here is
promiscuous mode, otherwise yea we usually use the highest filtering
level. When changing the "filtering level" it depends on interface
type what we need to filter in softmac then and what's not. One thing
in promiscuous mode and everything else than monitor is to check on if
the checksum is valid and drop if necessary, same for address
filtering, etc. I don't assume that the software filtering is 100%
correct, but we should have a basis to adding more filters if
necessary and we found something is missing?

What do you think?

 - Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 10/20] net: mac802154: Handle passive scanning
  2022-08-01 23:42     ` Alexander Aring
@ 2022-08-01 23:54       ` Alexander Aring
  0 siblings, 0 replies; 84+ messages in thread
From: Alexander Aring @ 2022-08-01 23:54 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Mon, Aug 1, 2022 at 7:42 PM Alexander Aring <aahringo@redhat.com> wrote:
>
> Hi,
>
> On Thu, Jul 14, 2022 at 11:33 PM Alexander Aring <aahringo@redhat.com> wrote:
> ...
> >
> > I know some driver datasheets and as I said before, it's not allowed
> > to set promiscuous mode while in receive mode. We need to stop tx,
> > what we are doing. Then call stop() driver callback,
> > synchronize_net(), mac802154_set_promiscuous_mode(...), start(). The
> > same always for the opposite.
> >
>
> I think we should try to work on that as a next patch series to offer
> such functionality in which "filtering level" the hardware should be
> "started". As I said it cannot be changed during runtime as
> "transceiver is being in receive mode" but there is the possibility to
> stop/start the hardware _transparent_ from the user to change the
> "filtering level". I say filtering level because I think this is what
> the standard uses as a term. The one which is needed here is
> promiscuous mode, otherwise yea we usually use the highest filtering
> level. When changing the "filtering level" it depends on interface
> type what we need to filter in softmac then and what's not. One thing
> in promiscuous mode and everything else than monitor is to check on if
> the checksum is valid and drop if necessary, same for address
> filtering, etc. I don't assume that the software filtering is 100%

forget the address filtering, this is only required when it operates
in non scan mode. It always depends, however you don't need to
implement it if it's not necessary. I think we should somehow get a
per parameter at receive path to know on which filtering level it was
received, then more handling in regarding which receive path it goes
can be made, e.g. if frame xy was received in promiscuous mode. For
scan you don't need to check address filter but checksum, other
receive path have different requirements (not saying that those exists
right now but may in future).

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 19/20] ieee802154: hwsim: Do not check the rtnl
  2022-07-06  1:23   ` Alexander Aring
@ 2022-08-01 23:58     ` Alexander Aring
  2022-08-19 17:09     ` Miquel Raynal
  1 sibling, 0 replies; 84+ messages in thread
From: Alexander Aring @ 2022-08-01 23:58 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Tue, Jul 5, 2022 at 9:23 PM Alexander Aring <aahringo@redhat.com> wrote:
>
> Hi,
>
> On Fri, Jul 1, 2022 at 10:37 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> >
> > There is no need to ensure the rtnl is locked when changing a driver's
> > channel. This cause issues when scanning and this is the only driver
> > relying on it. Just drop this dependency because it does not seem
> > legitimate.
> >
>
> switching channels relies on changing pib attributes, pib attributes
> are protected by rtnl. If you experience issues here then it's
> probably because you do something wrong. All drivers assuming here
> that rtnl lock is held.

especially this change could end in invalid free. Maybe we can solve
this problem in a different way, what exactly is the problem by
helding rtnl lock?

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 09/20] net: mac802154: Introduce a global device lock
  2022-07-04  1:12   ` Alexander Aring
@ 2022-08-19 17:06     ` Miquel Raynal
  0 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-08-19 17:06 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

I hope you've had a wonderful summer :-)

aahringo@redhat.com wrote on Sun, 3 Jul 2022 21:12:43 -0400:

> Hi,
> 
> On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> >
> > The purpose of this device lock is to prevent the removal of the device
> > while an asynchronous MLME operation happens. The RTNL works well for
> > that but in a later series having the RTNL taken here will be
> > problematic and will cause lockdep to warn us about a circular
> > dependency. We don't really need the RTNL here, just a serialization
> > over this operation.
> >
> > Replace the RTNL calls with this new lock.  
> 
> I am unhappy about this solution. Can we not interrupt the ongoing
> operation "scan" here and come to an end at a stop?
> 
> The RTNL is NOT only to prevent the removal of something... If mostly
> all operations are protected by and I know one which makes trouble
> here... setting page/channel. I know we don't hold the rtnl lock on
> other transmit functionality for phy settings which has other reasons
> why we allow it... but here we offer a mac operation which delivers
> wrong results if somebody does another setting e.g. set page/channel
> while scan is going on and we should prevent this.
> 
> Dropping the rtnl lock, yes we can do that... I cannot think about all
> the side effects which this change will bring into, one I know is the
> channel setting, mostly everything that is interfering with a scan and
> then ugly things which we don't want... preparing the code for the
> page/channel gives us a direction on how to fix and check the other
> cases if we find them. btw: we should do this on another approach
> anyway because the rtnl lock is not held during a whole operation and
> we don't want that.
> 
> We should also take care that we hold some references which we held
> during the scan, even if it's protected by stop (just for
> correctness).

I was also a bit unhappy by this solution but the rtnl is a real mess
when playing with background works. At least I was not able at all to
make it fit. I'm gonna try to summarize the situation to argue in favor
of the current solution, but I am really open if you see another way.

A scan is started by the user, through a netlink command. It basically
involves stopping any other activity on the transceiver, setting a
particular filtering mode, and possibly sending beacons through the MLME
Tx API at a regular interval.

A scan command from the user then involves acquiring the rtnl just to
be sure that nothing else is requested in parallel. The rtnl is taken
and released by the netlink core, just for the time of the
configuring/triggering action.

We absolutely do not want to keep the rtnl here, I believe we are
aligned on that. This means we need to protect ourselves against a
number of user actions:
1- dropping the device (without stopping the background job/cleaning
   everything),
2- transmitting packets
3- changing internal parameters such as the page/channel to avoid
   messing with the ongoing scan.

The current implementation does the following:
1- in the ieee802154 layer we call dev_hold/dev_put to prevent device
   removal,
2- in the soft mac layer we stop the queue,
3- in the soft mac layer we refuse any channel change command coming
   from the netlink layer during scans, because this is not a nl
   constraint, but a mac state constraint, so I think it is safe to
   handle that from the soft mac layer rather than at the nl level.

This is how I planned to handle the refcount and channel change issues.

Now, let me try to argue in favor of this commit.

The problem I faced was a circular dependency on the device sending
beacons or beacons requests, ie. sending MLME frames in the background.
For the record, in both cases, I need to put some parameters in one of
the main soft mac structures. I created local->scan_lock and
local->beacon_lock to protect accesses to the scanning and beaconing
structures respectively (we don't want eg. the struct to be freed while
a job is using it).

Let's take the situation of the device sending beacons in the
background.

For starting to send beacons, the user sends a netlink command. In the
kernel first layers, the rtnl is acquired (almost) automatically, then
the callback function in the soft mac does the job. One of the first
operations is to acquire the beacons_lock.

Lockdep detects that during the background operation, the kworker will
first acquire beacons_lock (it encloses the whole operation) and after
acquiring this first lock it will perform an MLME Tx to send the
beacon. But this, unfortunately, acquires the rtnl, which triggers the
following warning:

[ 1445.105706]  Possible unsafe locking scenario:
//               -> background job            -> nl802154_send_beacons()   
[ 1445.105707]        CPU0                    CPU1
[ 1445.105708]        ----                    ----
[ 1445.105709]   lock(&local->beacon_lock);
[ 1445.105710]                                lock(rtnl_mutex);
[ 1445.105712]                                lock(&local->beacon_lock);
[ 1445.105713]   lock(rtnl_mutex);

Exactly the same happens in the scanning path during active scans:

[   52.518741]  Possible unsafe locking scenario:
//               -> background job            -> nl802154_trigger_scan()
[   52.518742]        CPU0                    CPU1
[   52.518743]        ----                    ----
[   52.518744]   lock(&local->scan_lock);
[   52.518746]                                lock(rtnl_mutex);
[   52.518748]                                lock(&local->scan_lock);
[   52.518750]   lock(rtnl_mutex);

In practice I doubt these situations can really happen because there is
no background job running if the triggering netlink command was not
yet called, but anyway, I feel too weak against locking scenarios
to disobey such a clear lockdep warning :-)

So, from my understanding it was safe not to acquire the rtnl in the
MLME Tx path, as long as the calls were serialized (with another
mutex). You seem not to agree with it, which I completely understand,
but then how do I handle those circular dependencies?

Do you think like me they are false positives?

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 19/20] ieee802154: hwsim: Do not check the rtnl
  2022-07-06  1:23   ` Alexander Aring
  2022-08-01 23:58     ` Alexander Aring
@ 2022-08-19 17:09     ` Miquel Raynal
  2022-08-25 22:41       ` Miquel Raynal
  1 sibling, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-08-19 17:09 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Tue, 5 Jul 2022 21:23:21 -0400:

> Hi,
> 
> On Fri, Jul 1, 2022 at 10:37 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> >
> > There is no need to ensure the rtnl is locked when changing a driver's
> > channel. This cause issues when scanning and this is the only driver
> > relying on it. Just drop this dependency because it does not seem
> > legitimate.
> >  
> 
> switching channels relies on changing pib attributes, pib attributes
> are protected by rtnl. If you experience issues here then it's
> probably because you do something wrong. All drivers assuming here
> that rtnl lock is held.

---8<---
> especially this change could end in invalid free. Maybe we can solve
> this problem in a different way, what exactly is the problem by
> helding rtnl lock?
--->8---

During a scan we need to change channels. So when the background job
kicks-in, we first acquire scan_lock, then we check the internal
parameters of the structure protected by this lock, like the next
channel to use and the sdata pointer. A channel change must be
performed, preceded by an rtnl_lock(). This will again trigger a
possible circular lockdep dependency warning because the triggering path
acquires the rtnl (as part of the netlink layer) before the scan lock.

One possible solution would be to do the following:
scan_work() {
	acquire(scan_lock);
	// do some config
	release(scan_lock);
	rtnl_lock();
	perform_channel_change();
	rtnl_unlock();
	acquire(scan_lock);
	// reinit the scan struct ptr and the sdata ptr
	// do some more things
	release(scan_lock);
}

It looks highly non-elegant IMHO. Otherwise I need to stop verifying in
the drivers that the rtnl is taken. Any third option here?

BTW I don't see where the invalid free situation you mentioned can
happen here, can you explain?

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-07-06  1:51   ` Alexander Aring
@ 2022-08-19 17:11     ` Miquel Raynal
  2022-08-23 12:33       ` Alexander Aring
  0 siblings, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-08-19 17:11 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Tue, 5 Jul 2022 21:51:02 -0400:

> Hi,
> 
> On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> >
> > As a first strep in introducing proper PAN management and association,
> > we need to be able to create coordinator interfaces which might act as
> > coordinator or PAN coordinator.
> >
> > Hence, let's add the minimum support to allow the creation of these
> > interfaces. This might be restrained and improved later.
> >
> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > ---
> >  net/mac802154/iface.c | 14 ++++++++------
> >  net/mac802154/rx.c    |  2 +-
> >  2 files changed, 9 insertions(+), 7 deletions(-)
> >
> > diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
> > index 500ed1b81250..7ac0c5685d3f 100644
> > --- a/net/mac802154/iface.c
> > +++ b/net/mac802154/iface.c
> > @@ -273,13 +273,13 @@ ieee802154_check_concurrent_iface(struct ieee802154_sub_if_data *sdata,
> >                 if (nsdata != sdata && ieee802154_sdata_running(nsdata)) {
> >                         int ret;
> >
> > -                       /* TODO currently we don't support multiple node types
> > -                        * we need to run skb_clone at rx path. Check if there
> > -                        * exist really an use case if we need to support
> > -                        * multiple node types at the same time.
> > +                       /* TODO currently we don't support multiple node/coord
> > +                        * types we need to run skb_clone at rx path. Check if
> > +                        * there exist really an use case if we need to support
> > +                        * multiple node/coord types at the same time.
> >                          */
> > -                       if (wpan_dev->iftype == NL802154_IFTYPE_NODE &&
> > -                           nsdata->wpan_dev.iftype == NL802154_IFTYPE_NODE)
> > +                       if (wpan_dev->iftype != NL802154_IFTYPE_MONITOR &&
> > +                           nsdata->wpan_dev.iftype != NL802154_IFTYPE_MONITOR)
> >                                 return -EBUSY;
> >
> >                         /* check all phy mac sublayer settings are the same.
> > @@ -577,6 +577,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
> >         wpan_dev->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
> >
> >         switch (type) {
> > +       case NL802154_IFTYPE_COORD:
> >         case NL802154_IFTYPE_NODE:
> >                 ieee802154_be64_to_le64(&wpan_dev->extended_addr,
> >                                         sdata->dev->dev_addr);
> > @@ -636,6 +637,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
> >         ieee802154_le64_to_be64(ndev->perm_addr,
> >                                 &local->hw.phy->perm_extended_addr);
> >         switch (type) {
> > +       case NL802154_IFTYPE_COORD:
> >         case NL802154_IFTYPE_NODE:
> >                 ndev->type = ARPHRD_IEEE802154;
> >                 if (ieee802154_is_valid_extended_unicast_addr(extended_addr)) {
> > diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
> > index b8ce84618a55..39459d8d787a 100644
> > --- a/net/mac802154/rx.c
> > +++ b/net/mac802154/rx.c
> > @@ -203,7 +203,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> >         }
> >
> >         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> > -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> > +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
> >                         continue;  
> 
> I probably get why you are doing that, but first the overall design is
> working differently - means you should add an additional receive path
> for the special interface type.
> 
> Also we "discovered" before that the receive path of node vs
> coordinator is different... Where is the different handling here? I
> don't see it, I see that NODE and COORD are the same now (because that
> is _currently_ everything else than monitor). This change is not
> enough and does "something" to handle in some way coordinator receive
> path but there are things missing.
> 
> 1. Changing the address filters that it signals the transceiver it's
> acting as coordinator
> 2. We _should_ also have additional handling for whatever the
> additional handling what address filters are doing in mac802154
> _because_ there is hardware which doesn't have address filtering e.g.
> hwsim which depend that this is working in software like other
> transceiver hardware address filters.
> 
> For the 2. one, I don't know if we do that even for NODE right or we
> just have the bare minimal support there... I don't assume that
> everything is working correctly here but what I want to see is a
> separate receive path for coordinators that people can send patches to
> fix it.

Yes, we do very little differently between the two modes, that's why I
took the easy way: just changing the condition. I really don't see what
I can currently add here, but I am fine changing the style to easily
show people where to add filters for such or such interface, but right
now both path will look very "identical", do we agree on that?

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 20/20] ieee802154: hwsim: Allow devices to be coordinators
  2022-07-11  2:01   ` Alexander Aring
@ 2022-08-19 17:12     ` Miquel Raynal
  0 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-08-19 17:12 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Sun, 10 Jul 2022 22:01:43 -0400:

> Hi,
> 
> On Fri, Jul 1, 2022 at 10:37 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> >
> > In order to be able to create coordinator interfaces, we need the
> > drivers to advertize that they support this type of interface. Fill in
> > the right bit in the hwsim capabilities to allow the creation of these
> > coordinator interfaces.
> >
> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > ---
> >  drivers/net/ieee802154/mac802154_hwsim.c | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c
> > index a5b9fc2fb64c..a678ede07219 100644
> > --- a/drivers/net/ieee802154/mac802154_hwsim.c
> > +++ b/drivers/net/ieee802154/mac802154_hwsim.c
> > @@ -776,6 +776,8 @@ static int hwsim_add_one(struct genl_info *info, struct device *dev,
> >         /* 950 MHz GFSK 802.15.4d-2009 */
> >         hw->phy->supported.channels[6] |= 0x3ffc00;
> >
> > +       hw->phy->supported.iftypes |= BIT(NL802154_IFTYPE_COORD);  
> 
> I think we can do that for more than one driver (except ca8210).

Yes of course. I can update this patch and make the change to all the
drivers except ca8210 indeed.

> What about the other iftypes?

The NODE type is set by default at initialization time:
net/mac802154/main.c-120-       /* always supported */
net/mac802154/main.c:121:       phy->supported.iftypes = BIT(NL802154_IFTYPE_NODE);

The MONITOR type is only set if the device supports the promiscuous
mode:
net/mac802154/main.c-255-       if (hw->flags & IEEE802154_HW_PROMISCUOUS)
net/mac802154/main.c:256:               local->phy->supported.iftypes |= BIT(NL802154_IFTYPE_MONITOR);

Which indeed makes echo to one of your other review, saying that we
should probably prevent the creation of MONITOR types if the device has
no promiscuous support.

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 05/20] net: ieee802154: Define frame types
  2022-07-11  2:06   ` Alexander Aring
@ 2022-08-19 17:13     ` Miquel Raynal
  0 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-08-19 17:13 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Sun, 10 Jul 2022 22:06:57 -0400:

> Hi,
> 
> On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> >
> > A 802.15.4 frame can be of different types, here is a definition
> > matching the specification. This enumeration will be soon be used when
> > adding scanning support.
> >
> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > ---
> >  include/net/ieee802154_netdev.h | 11 +++++++++++
> >  1 file changed, 11 insertions(+)
> >
> > diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
> > index d0d188c3294b..13167851b1c3 100644
> > --- a/include/net/ieee802154_netdev.h
> > +++ b/include/net/ieee802154_netdev.h
> > @@ -69,6 +69,17 @@ struct ieee802154_hdr_fc {
> >  #endif
> >  };
> >
> > +enum ieee802154_frame_type {
> > +       IEEE802154_BEACON_FRAME,
> > +       IEEE802154_DATA_FRAME,
> > +       IEEE802154_ACKNOWLEDGEMENT_FRAME,
> > +       IEEE802154_MAC_COMMAND_FRAME,
> > +       IEEE802154_RESERVED_FRAME,
> > +       IEEE802154_MULTIPURPOSE_FRAME,
> > +       IEEE802154_FRAGMENT_FRAME,
> > +       IEEE802154_EXTENDED_FRAME,
> > +};  
> 
> Please use and extend include/linux/ieee802154.h e.g. IEEE802154_FC_TYPE_DATA.
> I am also not a fan of putting those structs on payload, because there
> can be several problems with it, we should introduce inline helpers to
> check/get each individual fields but... the struct is currently how
> it's implemented.

Ok, I can easily do that.

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 17/20] net: ieee802154: Handle limited devices with only datagram support
  2022-07-15  3:16   ` Alexander Aring
@ 2022-08-19 17:13     ` Miquel Raynal
  2022-08-23 12:43       ` Alexander Aring
  0 siblings, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-08-19 17:13 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Thu, 14 Jul 2022 23:16:33 -0400:

> Hi,
> 
> On Fri, Jul 1, 2022 at 10:37 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> >
> > Some devices, like HardMAC ones can be a bit limited in the way they
> > handle mac commands. In particular, they might just not support it at
> > all and instead only be able to transmit and receive regular data
> > packets. In this case, they cannot be used for any of the internal
> > management commands that we have introduced so far and must be flagged
> > accordingly.
> >
> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > ---
> >  include/net/cfg802154.h   | 3 +++
> >  net/ieee802154/nl802154.c | 6 ++++++
> >  2 files changed, 9 insertions(+)
> >
> > diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
> > index d6ff60d900a9..20ac4df9dc7b 100644
> > --- a/include/net/cfg802154.h
> > +++ b/include/net/cfg802154.h
> > @@ -178,12 +178,15 @@ wpan_phy_cca_cmp(const struct wpan_phy_cca *a, const struct wpan_phy_cca *b)
> >   *     setting.
> >   * @WPAN_PHY_FLAG_STATE_QUEUE_STOPPED: Indicates that the transmit queue was
> >   *     temporarily stopped.
> > + * @WPAN_PHY_FLAG_DATAGRAMS_ONLY: Indicates that transceiver is only able to
> > + *     send/receive datagrams.
> >   */
> >  enum wpan_phy_flags {
> >         WPAN_PHY_FLAG_TXPOWER           = BIT(1),
> >         WPAN_PHY_FLAG_CCA_ED_LEVEL      = BIT(2),
> >         WPAN_PHY_FLAG_CCA_MODE          = BIT(3),
> >         WPAN_PHY_FLAG_STATE_QUEUE_STOPPED = BIT(4),
> > +       WPAN_PHY_FLAG_DATAGRAMS_ONLY    = BIT(5),
> >  };
> >
> >  struct wpan_phy {
> > diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
> > index 00b03c33e826..b31a0bd36b08 100644
> > --- a/net/ieee802154/nl802154.c
> > +++ b/net/ieee802154/nl802154.c
> > @@ -1404,6 +1404,9 @@ static int nl802154_trigger_scan(struct sk_buff *skb, struct genl_info *info)
> >         if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
> >                 return -EPERM;
> >
> > +       if (wpan_phy->flags & WPAN_PHY_FLAG_DATAGRAMS_ONLY)
> > +               return -EOPNOTSUPP;
> > +  
> 
> for doing a scan it's also required to turn the transceiver into
> promiscuous mode, right?
> 
> There is currently a flag if a driver supports promiscuous mode or
> not... I am not sure if all drivers have support for it. For me it
> looks like a mandatory feature but I am not sure if every driver
> supports it.
> We have a similar situation with acknowledge retransmit handling...
> some transceivers can't handle it and for normal dataframes we have a
> default behaviour that we don't set it. However sometimes it's
> required by the spec, then we can't do anything here.
> 
> I think we should check on it but we should plan to drop this flag if
> promiscuous mode is supported or not.

Yes, you are right, I should check this flag is set, I will do it at
the creation of the MONITOR interface, which anyway does not make sense
if the device has no filtering support (promiscuous being a very
standard one, but, as you said below, will later be replaced by some
more advanced levels).

> I also think that the
> promiscuous driver_ops should be removed and moved as a parameter for
> start() driver_ops to declare which "receive mode" should be
> enabled... but we can do that in due course.

Agreed.

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 10/20] net: mac802154: Handle passive scanning
  2022-07-15  3:42     ` Alexander Aring
@ 2022-08-19 17:22       ` Miquel Raynal
  0 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-08-19 17:22 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Thu, 14 Jul 2022 23:42:08 -0400:

> Hi,
> 
> On Thu, Jul 14, 2022 at 11:33 PM Alexander Aring <aahringo@redhat.com> wrote:
> >
> > Hi,
> >
> > On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > >
> > > Implement the core hooks in order to provide the softMAC layer support
> > > for passive scans. Scans are requested by the user and can be aborted.
> > >
> > > Changing the channels is prohibited during the scan.
> > >
> > > As transceivers enter promiscuous mode during scans, they might stop
> > > checking frame validity so we ensure this gets done at mac level.
> > >
> > > The implementation uses a workqueue triggered at a certain interval
> > > depending on the symbol duration for the current channel and the
> > > duration order provided.
> > >
> > > Received beacons during a passive scan are processed also in a work
> > > queue and forwarded to the upper layer.
> > >
> > > Active scanning is not supported yet.
> > >
> > > Co-developed-by: David Girault <david.girault@qorvo.com>
> > > Signed-off-by: David Girault <david.girault@qorvo.com>
> > > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > > ---
> > >  include/linux/ieee802154.h   |   4 +
> > >  include/net/cfg802154.h      |  12 ++
> > >  net/mac802154/Makefile       |   2 +-
> > >  net/mac802154/cfg.c          |  39 ++++++
> > >  net/mac802154/ieee802154_i.h |  29 ++++
> > >  net/mac802154/iface.c        |   6 +
> > >  net/mac802154/main.c         |   4 +
> > >  net/mac802154/rx.c           |  49 ++++++-
> > >  net/mac802154/scan.c         | 264 +++++++++++++++++++++++++++++++++++
> > >  9 files changed, 405 insertions(+), 4 deletions(-)
> > >  create mode 100644 net/mac802154/scan.c
> > >

[...]

> > > +int mac802154_trigger_scan_locked(struct
ieee802154_sub_if_data *sdata,
> > > +                                 struct cfg802154_scan_request *request)
> > > +{
> > > +       struct ieee802154_local *local = sdata->local;
> > > +       int ret;
> > > +
> > > +       lockdep_assert_held(&local->scan_lock);
> > > +
> > > +       if (mac802154_is_scanning(local))
> > > +               return -EBUSY;
> > > +
> > > +       /* TODO: support other scanning type */
> > > +       if (request->type != NL802154_SCAN_PASSIVE)
> > > +               return -EOPNOTSUPP;
> > > +
> > > +       /* Store scanning parameters */
> > > +       rcu_assign_pointer(local->scan_req, request);
> > > +
> > > +       /* Software scanning requires to set promiscuous mode, so we need to
> > > +        * pause the Tx queue during the entire operation.
> > > +        */
> > > +       ieee802154_mlme_op_pre(local);
> > > +
> > > +       ret = mac802154_set_promiscuous_mode(local, true);
> > > +       if (ret)
> > > +               goto cancel_mlme;  
> >
> > I know some driver datasheets and as I said before, it's not allowed
> > to set promiscuous mode while in receive mode. We need to stop tx,
> > what we are doing. Then call stop() driver callback,
> > synchronize_net(), mac802154_set_promiscuous_mode(...), start(). The
> > same always for the opposite.  
>
> s/always/as well/

Mmmh. I didn't know. I will look into it.

> I need to say, it needs to be something like that... we need to be
> careful here e.g. lots of monitor interfaces on one phy which has
> currently a serious use case for hwsim.
> 
> We also don't need to do anything above if we already are in
> promiscuous mode, which might be worth checking.

True!

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-19 17:11     ` Miquel Raynal
@ 2022-08-23 12:33       ` Alexander Aring
  2022-08-23 16:29         ` Miquel Raynal
  0 siblings, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-08-23 12:33 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Fri, Aug 19, 2022 at 1:11 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> Hi Alexander,
>
> aahringo@redhat.com wrote on Tue, 5 Jul 2022 21:51:02 -0400:
>
> > Hi,
> >
> > On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > >
> > > As a first strep in introducing proper PAN management and association,
> > > we need to be able to create coordinator interfaces which might act as
> > > coordinator or PAN coordinator.
> > >
> > > Hence, let's add the minimum support to allow the creation of these
> > > interfaces. This might be restrained and improved later.
> > >
> > > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > > ---
> > >  net/mac802154/iface.c | 14 ++++++++------
> > >  net/mac802154/rx.c    |  2 +-
> > >  2 files changed, 9 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
> > > index 500ed1b81250..7ac0c5685d3f 100644
> > > --- a/net/mac802154/iface.c
> > > +++ b/net/mac802154/iface.c
> > > @@ -273,13 +273,13 @@ ieee802154_check_concurrent_iface(struct ieee802154_sub_if_data *sdata,
> > >                 if (nsdata != sdata && ieee802154_sdata_running(nsdata)) {
> > >                         int ret;
> > >
> > > -                       /* TODO currently we don't support multiple node types
> > > -                        * we need to run skb_clone at rx path. Check if there
> > > -                        * exist really an use case if we need to support
> > > -                        * multiple node types at the same time.
> > > +                       /* TODO currently we don't support multiple node/coord
> > > +                        * types we need to run skb_clone at rx path. Check if
> > > +                        * there exist really an use case if we need to support
> > > +                        * multiple node/coord types at the same time.
> > >                          */
> > > -                       if (wpan_dev->iftype == NL802154_IFTYPE_NODE &&
> > > -                           nsdata->wpan_dev.iftype == NL802154_IFTYPE_NODE)
> > > +                       if (wpan_dev->iftype != NL802154_IFTYPE_MONITOR &&
> > > +                           nsdata->wpan_dev.iftype != NL802154_IFTYPE_MONITOR)
> > >                                 return -EBUSY;
> > >
> > >                         /* check all phy mac sublayer settings are the same.
> > > @@ -577,6 +577,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
> > >         wpan_dev->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
> > >
> > >         switch (type) {
> > > +       case NL802154_IFTYPE_COORD:
> > >         case NL802154_IFTYPE_NODE:
> > >                 ieee802154_be64_to_le64(&wpan_dev->extended_addr,
> > >                                         sdata->dev->dev_addr);
> > > @@ -636,6 +637,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
> > >         ieee802154_le64_to_be64(ndev->perm_addr,
> > >                                 &local->hw.phy->perm_extended_addr);
> > >         switch (type) {
> > > +       case NL802154_IFTYPE_COORD:
> > >         case NL802154_IFTYPE_NODE:
> > >                 ndev->type = ARPHRD_IEEE802154;
> > >                 if (ieee802154_is_valid_extended_unicast_addr(extended_addr)) {
> > > diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
> > > index b8ce84618a55..39459d8d787a 100644
> > > --- a/net/mac802154/rx.c
> > > +++ b/net/mac802154/rx.c
> > > @@ -203,7 +203,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > >         }
> > >
> > >         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> > > -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> > > +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
> > >                         continue;
> >
> > I probably get why you are doing that, but first the overall design is
> > working differently - means you should add an additional receive path
> > for the special interface type.
> >
> > Also we "discovered" before that the receive path of node vs
> > coordinator is different... Where is the different handling here? I
> > don't see it, I see that NODE and COORD are the same now (because that
> > is _currently_ everything else than monitor). This change is not
> > enough and does "something" to handle in some way coordinator receive
> > path but there are things missing.
> >
> > 1. Changing the address filters that it signals the transceiver it's
> > acting as coordinator
> > 2. We _should_ also have additional handling for whatever the
> > additional handling what address filters are doing in mac802154
> > _because_ there is hardware which doesn't have address filtering e.g.
> > hwsim which depend that this is working in software like other
> > transceiver hardware address filters.
> >
> > For the 2. one, I don't know if we do that even for NODE right or we
> > just have the bare minimal support there... I don't assume that
> > everything is working correctly here but what I want to see is a
> > separate receive path for coordinators that people can send patches to
> > fix it.
>
> Yes, we do very little differently between the two modes, that's why I
> took the easy way: just changing the condition. I really don't see what
> I can currently add here, but I am fine changing the style to easily
> show people where to add filters for such or such interface, but right
> now both path will look very "identical", do we agree on that?

mostly yes, but there exists a difference and we should at least check
if the node receive path violates the coordinator receive path and
vice versa.
Put it in a receive_path() function and then coord_receive_path(),
node_receive_path() that calls the receive_path() and do the
additional filtering for coordinators, etc.

There should be a part in the standard about "third level filter rule
if it's a coordinator".
btw: this is because the address filter on the transceiver needs to
have the "i am a coordinator" boolean set which is missing in this
series. However it depends on the transceiver filtering level and the
mac802154 receive path if we actually need to run such filtering or
not.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 17/20] net: ieee802154: Handle limited devices with only datagram support
  2022-08-19 17:13     ` Miquel Raynal
@ 2022-08-23 12:43       ` Alexander Aring
  0 siblings, 0 replies; 84+ messages in thread
From: Alexander Aring @ 2022-08-23 12:43 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Fri, Aug 19, 2022 at 1:13 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> Hi Alexander,
>
> aahringo@redhat.com wrote on Thu, 14 Jul 2022 23:16:33 -0400:
>
> > Hi,
> >
> > On Fri, Jul 1, 2022 at 10:37 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > >
> > > Some devices, like HardMAC ones can be a bit limited in the way they
> > > handle mac commands. In particular, they might just not support it at
> > > all and instead only be able to transmit and receive regular data
> > > packets. In this case, they cannot be used for any of the internal
> > > management commands that we have introduced so far and must be flagged
> > > accordingly.
> > >
> > > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > > ---
> > >  include/net/cfg802154.h   | 3 +++
> > >  net/ieee802154/nl802154.c | 6 ++++++
> > >  2 files changed, 9 insertions(+)
> > >
> > > diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
> > > index d6ff60d900a9..20ac4df9dc7b 100644
> > > --- a/include/net/cfg802154.h
> > > +++ b/include/net/cfg802154.h
> > > @@ -178,12 +178,15 @@ wpan_phy_cca_cmp(const struct wpan_phy_cca *a, const struct wpan_phy_cca *b)
> > >   *     setting.
> > >   * @WPAN_PHY_FLAG_STATE_QUEUE_STOPPED: Indicates that the transmit queue was
> > >   *     temporarily stopped.
> > > + * @WPAN_PHY_FLAG_DATAGRAMS_ONLY: Indicates that transceiver is only able to
> > > + *     send/receive datagrams.
> > >   */
> > >  enum wpan_phy_flags {
> > >         WPAN_PHY_FLAG_TXPOWER           = BIT(1),
> > >         WPAN_PHY_FLAG_CCA_ED_LEVEL      = BIT(2),
> > >         WPAN_PHY_FLAG_CCA_MODE          = BIT(3),
> > >         WPAN_PHY_FLAG_STATE_QUEUE_STOPPED = BIT(4),
> > > +       WPAN_PHY_FLAG_DATAGRAMS_ONLY    = BIT(5),
> > >  };
> > >
> > >  struct wpan_phy {
> > > diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
> > > index 00b03c33e826..b31a0bd36b08 100644
> > > --- a/net/ieee802154/nl802154.c
> > > +++ b/net/ieee802154/nl802154.c
> > > @@ -1404,6 +1404,9 @@ static int nl802154_trigger_scan(struct sk_buff *skb, struct genl_info *info)
> > >         if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
> > >                 return -EPERM;
> > >
> > > +       if (wpan_phy->flags & WPAN_PHY_FLAG_DATAGRAMS_ONLY)
> > > +               return -EOPNOTSUPP;
> > > +
> >
> > for doing a scan it's also required to turn the transceiver into
> > promiscuous mode, right?
> >
> > There is currently a flag if a driver supports promiscuous mode or
> > not... I am not sure if all drivers have support for it. For me it
> > looks like a mandatory feature but I am not sure if every driver
> > supports it.
> > We have a similar situation with acknowledge retransmit handling...
> > some transceivers can't handle it and for normal dataframes we have a
> > default behaviour that we don't set it. However sometimes it's
> > required by the spec, then we can't do anything here.
> >
> > I think we should check on it but we should plan to drop this flag if
> > promiscuous mode is supported or not.
>
> Yes, you are right, I should check this flag is set, I will do it at
> the creation of the MONITOR interface, which anyway does not make sense
> if the device has no filtering support (promiscuous being a very
> standard one, but, as you said below, will later be replaced by some
> more advanced levels).
>
> > I also think that the
> > promiscuous driver_ops should be removed and moved as a parameter for
> > start() driver_ops to declare which "receive mode" should be
> > enabled... but we can do that in due course.
>
> Agreed.

We need to keep in mind that hwsim is a transceiver which only can run
in promiscuous mode and all receive paths need to be aware of this.
Yes, we can do that by saying on the ieee802154_rx() it always
receives frames in promiscuous mode and mac802154 does all the
filtering. I have the feeling there needs to be more done, because the
driver op to run into promiscuous mode and the mac802154 layer thinks
it's not BUT hwsim was it all the time. :-/

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-23 12:33       ` Alexander Aring
@ 2022-08-23 16:29         ` Miquel Raynal
  2022-08-23 21:44           ` Alexander Aring
  0 siblings, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-08-23 16:29 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Tue, 23 Aug 2022 08:33:30 -0400:

> Hi,
> 
> On Fri, Aug 19, 2022 at 1:11 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> >
> > Hi Alexander,
> >
> > aahringo@redhat.com wrote on Tue, 5 Jul 2022 21:51:02 -0400:
> >  
> > > Hi,
> > >
> > > On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > > >
> > > > As a first strep in introducing proper PAN management and association,
> > > > we need to be able to create coordinator interfaces which might act as
> > > > coordinator or PAN coordinator.
> > > >
> > > > Hence, let's add the minimum support to allow the creation of these
> > > > interfaces. This might be restrained and improved later.
> > > >
> > > > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > > > ---
> > > >  net/mac802154/iface.c | 14 ++++++++------
> > > >  net/mac802154/rx.c    |  2 +-
> > > >  2 files changed, 9 insertions(+), 7 deletions(-)
> > > >
> > > > diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
> > > > index 500ed1b81250..7ac0c5685d3f 100644
> > > > --- a/net/mac802154/iface.c
> > > > +++ b/net/mac802154/iface.c
> > > > @@ -273,13 +273,13 @@ ieee802154_check_concurrent_iface(struct ieee802154_sub_if_data *sdata,
> > > >                 if (nsdata != sdata && ieee802154_sdata_running(nsdata)) {
> > > >                         int ret;
> > > >
> > > > -                       /* TODO currently we don't support multiple node types
> > > > -                        * we need to run skb_clone at rx path. Check if there
> > > > -                        * exist really an use case if we need to support
> > > > -                        * multiple node types at the same time.
> > > > +                       /* TODO currently we don't support multiple node/coord
> > > > +                        * types we need to run skb_clone at rx path. Check if
> > > > +                        * there exist really an use case if we need to support
> > > > +                        * multiple node/coord types at the same time.
> > > >                          */
> > > > -                       if (wpan_dev->iftype == NL802154_IFTYPE_NODE &&
> > > > -                           nsdata->wpan_dev.iftype == NL802154_IFTYPE_NODE)
> > > > +                       if (wpan_dev->iftype != NL802154_IFTYPE_MONITOR &&
> > > > +                           nsdata->wpan_dev.iftype != NL802154_IFTYPE_MONITOR)
> > > >                                 return -EBUSY;
> > > >
> > > >                         /* check all phy mac sublayer settings are the same.
> > > > @@ -577,6 +577,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
> > > >         wpan_dev->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
> > > >
> > > >         switch (type) {
> > > > +       case NL802154_IFTYPE_COORD:
> > > >         case NL802154_IFTYPE_NODE:
> > > >                 ieee802154_be64_to_le64(&wpan_dev->extended_addr,
> > > >                                         sdata->dev->dev_addr);
> > > > @@ -636,6 +637,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
> > > >         ieee802154_le64_to_be64(ndev->perm_addr,
> > > >                                 &local->hw.phy->perm_extended_addr);
> > > >         switch (type) {
> > > > +       case NL802154_IFTYPE_COORD:
> > > >         case NL802154_IFTYPE_NODE:
> > > >                 ndev->type = ARPHRD_IEEE802154;
> > > >                 if (ieee802154_is_valid_extended_unicast_addr(extended_addr)) {
> > > > diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
> > > > index b8ce84618a55..39459d8d787a 100644
> > > > --- a/net/mac802154/rx.c
> > > > +++ b/net/mac802154/rx.c
> > > > @@ -203,7 +203,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > >         }
> > > >
> > > >         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> > > > -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> > > > +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
> > > >                         continue;  
> > >
> > > I probably get why you are doing that, but first the overall design is
> > > working differently - means you should add an additional receive path
> > > for the special interface type.
> > >
> > > Also we "discovered" before that the receive path of node vs
> > > coordinator is different... Where is the different handling here? I
> > > don't see it, I see that NODE and COORD are the same now (because that
> > > is _currently_ everything else than monitor). This change is not
> > > enough and does "something" to handle in some way coordinator receive
> > > path but there are things missing.
> > >
> > > 1. Changing the address filters that it signals the transceiver it's
> > > acting as coordinator
> > > 2. We _should_ also have additional handling for whatever the
> > > additional handling what address filters are doing in mac802154
> > > _because_ there is hardware which doesn't have address filtering e.g.
> > > hwsim which depend that this is working in software like other
> > > transceiver hardware address filters.
> > >
> > > For the 2. one, I don't know if we do that even for NODE right or we
> > > just have the bare minimal support there... I don't assume that
> > > everything is working correctly here but what I want to see is a
> > > separate receive path for coordinators that people can send patches to
> > > fix it.  
> >
> > Yes, we do very little differently between the two modes, that's why I
> > took the easy way: just changing the condition. I really don't see what
> > I can currently add here, but I am fine changing the style to easily
> > show people where to add filters for such or such interface, but right
> > now both path will look very "identical", do we agree on that?  
> 
> mostly yes, but there exists a difference and we should at least check
> if the node receive path violates the coordinator receive path and
> vice versa.
> Put it in a receive_path() function and then coord_receive_path(),
> node_receive_path() that calls the receive_path() and do the
> additional filtering for coordinators, etc.
> 
> There should be a part in the standard about "third level filter rule
> if it's a coordinator".
> btw: this is because the address filter on the transceiver needs to
> have the "i am a coordinator" boolean set which is missing in this
> series. However it depends on the transceiver filtering level and the
> mac802154 receive path if we actually need to run such filtering or
> not.

I must be missing some information because I can't find any places
where what you suggest is described in the spec.

I agree there are multiple filtering level so let's go through them one
by one (6.7.2 Reception and rejection):
- first level: is the checksum (FCS) valid?
	yes -> goto second level
	no -> drop
- second level: are we in promiscuous mode?
	yes -> forward to upper layers
	no -> goto second level (bis)
- second level (bis): are we scanning?
	yes -> goto scan filtering
	no -> goto third level
- scan filtering: is it a beacon?
	yes -> process the beacon
	no -> drop
- third level: is the frame valid? (type, source, destination, pan id,
  etc)
	yes -> forward to upper layers
	no -> drop

But none of them, as you said, is dependent on the interface type.
There is no mention of a specific filtering operation to do in all
those cases when running in COORD mode. So I still don't get what
should be included in either node_receive_path() which should be
different than in coord_receive_path() for now.

There are, however, two situations where the interface type has its
importance:
- Enhanced beacon requests with Enhanced beacon filter IE, which asks
  the receiving device to process/drop the request upon certain
  conditions (minimum LQI and/or randomness), as detailed in
  7.4.4.6 Enhanced Beacon Filter IE. But, as mentioned in
  7.5.9 Enhanced Beacon Request command: "The Enhanced Beacon Request
  command is optional for an FFD and an RFD", so this series was only
  targeting basic beaconing for now.
- In relaying mode, the destination address must not be validated
  because the message needs to be re-emitted. Indeed, a receiver in
  relaying mode may not be the recipient. This is also optional and out
  of the scope of this series.

Right now I have the below diff, which clarifies the two path, without
too much changes in the current code because I don't really see why it
would be necessary. Unless you convince me otherwise or read the spec
differently than I do :) What do you think?

Thanks,
Miquèl

---

--- a/net/mac802154/rx.c
+++ b/net/mac802154/rx.c
@@ -194,6 +194,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
        int ret;
        struct ieee802154_sub_if_data *sdata;
        struct ieee802154_hdr hdr;
+       bool iface_found = false;
 
        ret = ieee802154_parse_frame_start(skb, &hdr);
        if (ret) {
@@ -203,18 +204,31 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
        }
 
        list_for_each_entry_rcu(sdata, &local->interfaces, list) {
-               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
+               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
                        continue;
 
                if (!ieee802154_sdata_running(sdata))
                        continue;
 
+               iface_found = true;
+               break;
+       }
+
+       if (!iface_found) {
+               kfree_skb(skb);
+               return;
+       }
+
+       /* TBD: Additional filtering is possible on NODEs and/or COORDINATORs */
+       switch (sdata->wpan_dev.iftype) {
+       case NL802154_IFTYPE_COORD:
+       case NL802154_IFTYPE_NODE:
                ieee802154_subif_frame(sdata, skb, &hdr);
-               skb = NULL;
+               break;
+       default:
+               kfree_skb(skb);
                break;
        }
-
-       kfree_skb(skb);
 }
 
 static void

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-23 16:29         ` Miquel Raynal
@ 2022-08-23 21:44           ` Alexander Aring
  2022-08-24  7:35             ` Miquel Raynal
  2022-08-24 10:20             ` Miquel Raynal
  0 siblings, 2 replies; 84+ messages in thread
From: Alexander Aring @ 2022-08-23 21:44 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Tue, Aug 23, 2022 at 12:29 PM Miquel Raynal
<miquel.raynal@bootlin.com> wrote:
>
> Hi Alexander,
>
> aahringo@redhat.com wrote on Tue, 23 Aug 2022 08:33:30 -0400:
>
> > Hi,
> >
> > On Fri, Aug 19, 2022 at 1:11 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > >
> > > Hi Alexander,
> > >
> > > aahringo@redhat.com wrote on Tue, 5 Jul 2022 21:51:02 -0400:
> > >
> > > > Hi,
> > > >
> > > > On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > > >
> > > > > As a first strep in introducing proper PAN management and association,
> > > > > we need to be able to create coordinator interfaces which might act as
> > > > > coordinator or PAN coordinator.
> > > > >
> > > > > Hence, let's add the minimum support to allow the creation of these
> > > > > interfaces. This might be restrained and improved later.
> > > > >
> > > > > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > > > > ---
> > > > >  net/mac802154/iface.c | 14 ++++++++------
> > > > >  net/mac802154/rx.c    |  2 +-
> > > > >  2 files changed, 9 insertions(+), 7 deletions(-)
> > > > >
> > > > > diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
> > > > > index 500ed1b81250..7ac0c5685d3f 100644
> > > > > --- a/net/mac802154/iface.c
> > > > > +++ b/net/mac802154/iface.c
> > > > > @@ -273,13 +273,13 @@ ieee802154_check_concurrent_iface(struct ieee802154_sub_if_data *sdata,
> > > > >                 if (nsdata != sdata && ieee802154_sdata_running(nsdata)) {
> > > > >                         int ret;
> > > > >
> > > > > -                       /* TODO currently we don't support multiple node types
> > > > > -                        * we need to run skb_clone at rx path. Check if there
> > > > > -                        * exist really an use case if we need to support
> > > > > -                        * multiple node types at the same time.
> > > > > +                       /* TODO currently we don't support multiple node/coord
> > > > > +                        * types we need to run skb_clone at rx path. Check if
> > > > > +                        * there exist really an use case if we need to support
> > > > > +                        * multiple node/coord types at the same time.
> > > > >                          */
> > > > > -                       if (wpan_dev->iftype == NL802154_IFTYPE_NODE &&
> > > > > -                           nsdata->wpan_dev.iftype == NL802154_IFTYPE_NODE)
> > > > > +                       if (wpan_dev->iftype != NL802154_IFTYPE_MONITOR &&
> > > > > +                           nsdata->wpan_dev.iftype != NL802154_IFTYPE_MONITOR)
> > > > >                                 return -EBUSY;
> > > > >
> > > > >                         /* check all phy mac sublayer settings are the same.
> > > > > @@ -577,6 +577,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
> > > > >         wpan_dev->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
> > > > >
> > > > >         switch (type) {
> > > > > +       case NL802154_IFTYPE_COORD:
> > > > >         case NL802154_IFTYPE_NODE:
> > > > >                 ieee802154_be64_to_le64(&wpan_dev->extended_addr,
> > > > >                                         sdata->dev->dev_addr);
> > > > > @@ -636,6 +637,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
> > > > >         ieee802154_le64_to_be64(ndev->perm_addr,
> > > > >                                 &local->hw.phy->perm_extended_addr);
> > > > >         switch (type) {
> > > > > +       case NL802154_IFTYPE_COORD:
> > > > >         case NL802154_IFTYPE_NODE:
> > > > >                 ndev->type = ARPHRD_IEEE802154;
> > > > >                 if (ieee802154_is_valid_extended_unicast_addr(extended_addr)) {
> > > > > diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
> > > > > index b8ce84618a55..39459d8d787a 100644
> > > > > --- a/net/mac802154/rx.c
> > > > > +++ b/net/mac802154/rx.c
> > > > > @@ -203,7 +203,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > > >         }
> > > > >
> > > > >         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> > > > > -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> > > > > +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
> > > > >                         continue;
> > > >
> > > > I probably get why you are doing that, but first the overall design is
> > > > working differently - means you should add an additional receive path
> > > > for the special interface type.
> > > >
> > > > Also we "discovered" before that the receive path of node vs
> > > > coordinator is different... Where is the different handling here? I
> > > > don't see it, I see that NODE and COORD are the same now (because that
> > > > is _currently_ everything else than monitor). This change is not
> > > > enough and does "something" to handle in some way coordinator receive
> > > > path but there are things missing.
> > > >
> > > > 1. Changing the address filters that it signals the transceiver it's
> > > > acting as coordinator
> > > > 2. We _should_ also have additional handling for whatever the
> > > > additional handling what address filters are doing in mac802154
> > > > _because_ there is hardware which doesn't have address filtering e.g.
> > > > hwsim which depend that this is working in software like other
> > > > transceiver hardware address filters.
> > > >
> > > > For the 2. one, I don't know if we do that even for NODE right or we
> > > > just have the bare minimal support there... I don't assume that
> > > > everything is working correctly here but what I want to see is a
> > > > separate receive path for coordinators that people can send patches to
> > > > fix it.
> > >
> > > Yes, we do very little differently between the two modes, that's why I
> > > took the easy way: just changing the condition. I really don't see what
> > > I can currently add here, but I am fine changing the style to easily
> > > show people where to add filters for such or such interface, but right
> > > now both path will look very "identical", do we agree on that?
> >
> > mostly yes, but there exists a difference and we should at least check
> > if the node receive path violates the coordinator receive path and
> > vice versa.
> > Put it in a receive_path() function and then coord_receive_path(),
> > node_receive_path() that calls the receive_path() and do the
> > additional filtering for coordinators, etc.
> >
> > There should be a part in the standard about "third level filter rule
> > if it's a coordinator".
> > btw: this is because the address filter on the transceiver needs to
> > have the "i am a coordinator" boolean set which is missing in this
> > series. However it depends on the transceiver filtering level and the
> > mac802154 receive path if we actually need to run such filtering or
> > not.
>
> I must be missing some information because I can't find any places
> where what you suggest is described in the spec.
>
> I agree there are multiple filtering level so let's go through them one
> by one (6.7.2 Reception and rejection):
> - first level: is the checksum (FCS) valid?
>         yes -> goto second level
>         no -> drop
> - second level: are we in promiscuous mode?
>         yes -> forward to upper layers
>         no -> goto second level (bis)
> - second level (bis): are we scanning?
>         yes -> goto scan filtering
>         no -> goto third level
> - scan filtering: is it a beacon?
>         yes -> process the beacon
>         no -> drop
> - third level: is the frame valid? (type, source, destination, pan id,
>   etc)
>         yes -> forward to upper layers
>         no -> drop
>
> But none of them, as you said, is dependent on the interface type.
> There is no mention of a specific filtering operation to do in all
> those cases when running in COORD mode. So I still don't get what
> should be included in either node_receive_path() which should be
> different than in coord_receive_path() for now.
>
> There are, however, two situations where the interface type has its
> importance:
> - Enhanced beacon requests with Enhanced beacon filter IE, which asks
>   the receiving device to process/drop the request upon certain
>   conditions (minimum LQI and/or randomness), as detailed in
>   7.4.4.6 Enhanced Beacon Filter IE. But, as mentioned in
>   7.5.9 Enhanced Beacon Request command: "The Enhanced Beacon Request
>   command is optional for an FFD and an RFD", so this series was only
>   targeting basic beaconing for now.
> - In relaying mode, the destination address must not be validated
>   because the message needs to be re-emitted. Indeed, a receiver in
>   relaying mode may not be the recipient. This is also optional and out
>   of the scope of this series.
>
> Right now I have the below diff, which clarifies the two path, without
> too much changes in the current code because I don't really see why it
> would be necessary. Unless you convince me otherwise or read the spec
> differently than I do :) What do you think?
>

"Reception and rejection"

third-level filtering regarding "destination address" and if the
device is "PAN coordinator".
This is, in my opinion, what the coordinator boolean tells the
transceiver to do on hardware when doing address filter there. You can
also read that up in datasheets of transceivers as atf86rf233, search
for I_AM_COORD.

Whereas they use the word "PAN coordinator" not "coordinator", if they
really make a difference there at this point..., if so then the kernel
must know if the coordinator is a pan coordinator or coordinator
because we need to set the address filter in kernel.

> Thanks,
> Miquèl
>
> ---
>
> --- a/net/mac802154/rx.c
> +++ b/net/mac802154/rx.c
> @@ -194,6 +194,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
>         int ret;
>         struct ieee802154_sub_if_data *sdata;
>         struct ieee802154_hdr hdr;
> +       bool iface_found = false;
>
>         ret = ieee802154_parse_frame_start(skb, &hdr);
>         if (ret) {
> @@ -203,18 +204,31 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
>         }
>
>         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
>                         continue;
>
>                 if (!ieee802154_sdata_running(sdata))
>                         continue;
>
> +               iface_found = true;
> +               break;
> +       }
> +
> +       if (!iface_found) {
> +               kfree_skb(skb);
> +               return;
> +       }
> +
> +       /* TBD: Additional filtering is possible on NODEs and/or COORDINATORs */
> +       switch (sdata->wpan_dev.iftype) {
> +       case NL802154_IFTYPE_COORD:
> +       case NL802154_IFTYPE_NODE:
>                 ieee802154_subif_frame(sdata, skb, &hdr);
> -               skb = NULL;
> +               break;
> +       default:
> +               kfree_skb(skb);
>                 break;
>         }

Why do you remove the whole interface looping above and make it only
run for one ?first found? ? That code changes this behaviour and I do
not know why. Move the switch case into the loop and do a different
receive path if coord and node and do whatever differs from filtering
and then call ieee802154_subif_frame().

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-23 21:44           ` Alexander Aring
@ 2022-08-24  7:35             ` Miquel Raynal
  2022-08-24 21:43               ` Alexander Aring
  2022-08-24 10:20             ` Miquel Raynal
  1 sibling, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-08-24  7:35 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Tue, 23 Aug 2022 17:44:52 -0400:

> Hi,
> 
> On Tue, Aug 23, 2022 at 12:29 PM Miquel Raynal
> <miquel.raynal@bootlin.com> wrote:
> >
> > Hi Alexander,
> >
> > aahringo@redhat.com wrote on Tue, 23 Aug 2022 08:33:30 -0400:
> >  
> > > Hi,
> > >
> > > On Fri, Aug 19, 2022 at 1:11 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > > >
> > > > Hi Alexander,
> > > >
> > > > aahringo@redhat.com wrote on Tue, 5 Jul 2022 21:51:02 -0400:
> > > >  
> > > > > Hi,
> > > > >
> > > > > On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > > > > >
> > > > > > As a first strep in introducing proper PAN management and association,
> > > > > > we need to be able to create coordinator interfaces which might act as
> > > > > > coordinator or PAN coordinator.
> > > > > >
> > > > > > Hence, let's add the minimum support to allow the creation of these
> > > > > > interfaces. This might be restrained and improved later.
> > > > > >
> > > > > > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > > > > > ---
> > > > > >  net/mac802154/iface.c | 14 ++++++++------
> > > > > >  net/mac802154/rx.c    |  2 +-
> > > > > >  2 files changed, 9 insertions(+), 7 deletions(-)
> > > > > >
> > > > > > diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
> > > > > > index 500ed1b81250..7ac0c5685d3f 100644
> > > > > > --- a/net/mac802154/iface.c
> > > > > > +++ b/net/mac802154/iface.c
> > > > > > @@ -273,13 +273,13 @@ ieee802154_check_concurrent_iface(struct ieee802154_sub_if_data *sdata,
> > > > > >                 if (nsdata != sdata && ieee802154_sdata_running(nsdata)) {
> > > > > >                         int ret;
> > > > > >
> > > > > > -                       /* TODO currently we don't support multiple node types
> > > > > > -                        * we need to run skb_clone at rx path. Check if there
> > > > > > -                        * exist really an use case if we need to support
> > > > > > -                        * multiple node types at the same time.
> > > > > > +                       /* TODO currently we don't support multiple node/coord
> > > > > > +                        * types we need to run skb_clone at rx path. Check if
> > > > > > +                        * there exist really an use case if we need to support
> > > > > > +                        * multiple node/coord types at the same time.
> > > > > >                          */
> > > > > > -                       if (wpan_dev->iftype == NL802154_IFTYPE_NODE &&
> > > > > > -                           nsdata->wpan_dev.iftype == NL802154_IFTYPE_NODE)
> > > > > > +                       if (wpan_dev->iftype != NL802154_IFTYPE_MONITOR &&
> > > > > > +                           nsdata->wpan_dev.iftype != NL802154_IFTYPE_MONITOR)
> > > > > >                                 return -EBUSY;
> > > > > >
> > > > > >                         /* check all phy mac sublayer settings are the same.
> > > > > > @@ -577,6 +577,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
> > > > > >         wpan_dev->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
> > > > > >
> > > > > >         switch (type) {
> > > > > > +       case NL802154_IFTYPE_COORD:
> > > > > >         case NL802154_IFTYPE_NODE:
> > > > > >                 ieee802154_be64_to_le64(&wpan_dev->extended_addr,
> > > > > >                                         sdata->dev->dev_addr);
> > > > > > @@ -636,6 +637,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
> > > > > >         ieee802154_le64_to_be64(ndev->perm_addr,
> > > > > >                                 &local->hw.phy->perm_extended_addr);
> > > > > >         switch (type) {
> > > > > > +       case NL802154_IFTYPE_COORD:
> > > > > >         case NL802154_IFTYPE_NODE:
> > > > > >                 ndev->type = ARPHRD_IEEE802154;
> > > > > >                 if (ieee802154_is_valid_extended_unicast_addr(extended_addr)) {
> > > > > > diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
> > > > > > index b8ce84618a55..39459d8d787a 100644
> > > > > > --- a/net/mac802154/rx.c
> > > > > > +++ b/net/mac802154/rx.c
> > > > > > @@ -203,7 +203,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > > > >         }
> > > > > >
> > > > > >         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> > > > > > -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> > > > > > +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
> > > > > >                         continue;  
> > > > >
> > > > > I probably get why you are doing that, but first the overall design is
> > > > > working differently - means you should add an additional receive path
> > > > > for the special interface type.
> > > > >
> > > > > Also we "discovered" before that the receive path of node vs
> > > > > coordinator is different... Where is the different handling here? I
> > > > > don't see it, I see that NODE and COORD are the same now (because that
> > > > > is _currently_ everything else than monitor). This change is not
> > > > > enough and does "something" to handle in some way coordinator receive
> > > > > path but there are things missing.
> > > > >
> > > > > 1. Changing the address filters that it signals the transceiver it's
> > > > > acting as coordinator
> > > > > 2. We _should_ also have additional handling for whatever the
> > > > > additional handling what address filters are doing in mac802154
> > > > > _because_ there is hardware which doesn't have address filtering e.g.
> > > > > hwsim which depend that this is working in software like other
> > > > > transceiver hardware address filters.
> > > > >
> > > > > For the 2. one, I don't know if we do that even for NODE right or we
> > > > > just have the bare minimal support there... I don't assume that
> > > > > everything is working correctly here but what I want to see is a
> > > > > separate receive path for coordinators that people can send patches to
> > > > > fix it.  
> > > >
> > > > Yes, we do very little differently between the two modes, that's why I
> > > > took the easy way: just changing the condition. I really don't see what
> > > > I can currently add here, but I am fine changing the style to easily
> > > > show people where to add filters for such or such interface, but right
> > > > now both path will look very "identical", do we agree on that?  
> > >
> > > mostly yes, but there exists a difference and we should at least check
> > > if the node receive path violates the coordinator receive path and
> > > vice versa.
> > > Put it in a receive_path() function and then coord_receive_path(),
> > > node_receive_path() that calls the receive_path() and do the
> > > additional filtering for coordinators, etc.
> > >
> > > There should be a part in the standard about "third level filter rule
> > > if it's a coordinator".
> > > btw: this is because the address filter on the transceiver needs to
> > > have the "i am a coordinator" boolean set which is missing in this
> > > series. However it depends on the transceiver filtering level and the
> > > mac802154 receive path if we actually need to run such filtering or
> > > not.  
> >
> > I must be missing some information because I can't find any places
> > where what you suggest is described in the spec.
> >
> > I agree there are multiple filtering level so let's go through them one
> > by one (6.7.2 Reception and rejection):
> > - first level: is the checksum (FCS) valid?
> >         yes -> goto second level
> >         no -> drop
> > - second level: are we in promiscuous mode?
> >         yes -> forward to upper layers
> >         no -> goto second level (bis)
> > - second level (bis): are we scanning?
> >         yes -> goto scan filtering
> >         no -> goto third level
> > - scan filtering: is it a beacon?
> >         yes -> process the beacon
> >         no -> drop
> > - third level: is the frame valid? (type, source, destination, pan id,
> >   etc)
> >         yes -> forward to upper layers
> >         no -> drop
> >
> > But none of them, as you said, is dependent on the interface type.
> > There is no mention of a specific filtering operation to do in all
> > those cases when running in COORD mode. So I still don't get what
> > should be included in either node_receive_path() which should be
> > different than in coord_receive_path() for now.
> >
> > There are, however, two situations where the interface type has its
> > importance:
> > - Enhanced beacon requests with Enhanced beacon filter IE, which asks
> >   the receiving device to process/drop the request upon certain
> >   conditions (minimum LQI and/or randomness), as detailed in
> >   7.4.4.6 Enhanced Beacon Filter IE. But, as mentioned in
> >   7.5.9 Enhanced Beacon Request command: "The Enhanced Beacon Request
> >   command is optional for an FFD and an RFD", so this series was only
> >   targeting basic beaconing for now.
> > - In relaying mode, the destination address must not be validated
> >   because the message needs to be re-emitted. Indeed, a receiver in
> >   relaying mode may not be the recipient. This is also optional and out
> >   of the scope of this series.
> >
> > Right now I have the below diff, which clarifies the two path, without
> > too much changes in the current code because I don't really see why it
> > would be necessary. Unless you convince me otherwise or read the spec
> > differently than I do :) What do you think?
> >  
> 
> "Reception and rejection"
> 
> third-level filtering regarding "destination address" and if the
> device is "PAN coordinator".
> This is, in my opinion, what the coordinator boolean tells the
> transceiver to do on hardware when doing address filter there. You can
> also read that up in datasheets of transceivers as atf86rf233, search
> for I_AM_COORD.

Oh right, I now see what you mean!

> Whereas they use the word "PAN coordinator" not "coordinator", if they
> really make a difference there at this point..., if so then the kernel
> must know if the coordinator is a pan coordinator or coordinator
> because we need to set the address filter in kernel.

Yes we need to make a difference, you can have several coordinators but
a single PAN coordinator in a PAN. I think we can assume that the PAN
coordinator is the coordinator with no parent (association-wise). With
the addition of the association series, I can handle that, so I will
create the two path as you advise, add a comment about this additional
filter rule that we don't yet support, and finally after the
association series add another commit to make this filtering rule real.

> 
> > Thanks,
> > Miquèl
> >
> > ---
> >
> > --- a/net/mac802154/rx.c
> > +++ b/net/mac802154/rx.c
> > @@ -194,6 +194,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> >         int ret;
> >         struct ieee802154_sub_if_data *sdata;
> >         struct ieee802154_hdr hdr;
> > +       bool iface_found = false;
> >
> >         ret = ieee802154_parse_frame_start(skb, &hdr);
> >         if (ret) {
> > @@ -203,18 +204,31 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> >         }
> >
> >         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> > -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> > +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
> >                         continue;
> >
> >                 if (!ieee802154_sdata_running(sdata))
> >                         continue;
> >
> > +               iface_found = true;
> > +               break;
> > +       }
> > +
> > +       if (!iface_found) {
> > +               kfree_skb(skb);
> > +               return;
> > +       }
> > +
> > +       /* TBD: Additional filtering is possible on NODEs and/or COORDINATORs */
> > +       switch (sdata->wpan_dev.iftype) {
> > +       case NL802154_IFTYPE_COORD:
> > +       case NL802154_IFTYPE_NODE:
> >                 ieee802154_subif_frame(sdata, skb, &hdr);
> > -               skb = NULL;
> > +               break;
> > +       default:
> > +               kfree_skb(skb);
> >                 break;
> >         }  
> 
> Why do you remove the whole interface looping above and make it only
> run for one ?first found? ?

To reduce the indentation level.

> That code changes this behaviour and I do
> not know why.

The precedent code did:
for_each_iface() {
	if (not a node)
		continue;
	if (not running)
		continue;

	subif_frame();
	break;
}

That final break also elected only the first running node iface.
Otherwise it would mean that we allow the same skb to be consumed
twice, which is wrong IMHO?

> Move the switch case into the loop and do a different
> receive path if coord and node and do whatever differs from filtering
> and then call ieee802154_subif_frame().
> 
> - Alex
> 

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-23 21:44           ` Alexander Aring
  2022-08-24  7:35             ` Miquel Raynal
@ 2022-08-24 10:20             ` Miquel Raynal
  2022-08-24 12:43               ` Alexander Aring
  1 sibling, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-08-24 10:20 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Tue, 23 Aug 2022 17:44:52 -0400:

> Hi,
> 
> On Tue, Aug 23, 2022 at 12:29 PM Miquel Raynal
> <miquel.raynal@bootlin.com> wrote:
> >
> > Hi Alexander,
> >
> > aahringo@redhat.com wrote on Tue, 23 Aug 2022 08:33:30 -0400:
> >  
> > > Hi,
> > >
> > > On Fri, Aug 19, 2022 at 1:11 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > > >
> > > > Hi Alexander,
> > > >
> > > > aahringo@redhat.com wrote on Tue, 5 Jul 2022 21:51:02 -0400:
> > > >  
> > > > > Hi,
> > > > >
> > > > > On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > > > > >
> > > > > > As a first strep in introducing proper PAN management and association,
> > > > > > we need to be able to create coordinator interfaces which might act as
> > > > > > coordinator or PAN coordinator.
> > > > > >
> > > > > > Hence, let's add the minimum support to allow the creation of these
> > > > > > interfaces. This might be restrained and improved later.
> > > > > >
> > > > > > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > > > > > ---
> > > > > >  net/mac802154/iface.c | 14 ++++++++------
> > > > > >  net/mac802154/rx.c    |  2 +-
> > > > > >  2 files changed, 9 insertions(+), 7 deletions(-)
> > > > > >
> > > > > > diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
> > > > > > index 500ed1b81250..7ac0c5685d3f 100644
> > > > > > --- a/net/mac802154/iface.c
> > > > > > +++ b/net/mac802154/iface.c
> > > > > > @@ -273,13 +273,13 @@ ieee802154_check_concurrent_iface(struct ieee802154_sub_if_data *sdata,
> > > > > >                 if (nsdata != sdata && ieee802154_sdata_running(nsdata)) {
> > > > > >                         int ret;
> > > > > >
> > > > > > -                       /* TODO currently we don't support multiple node types
> > > > > > -                        * we need to run skb_clone at rx path. Check if there
> > > > > > -                        * exist really an use case if we need to support
> > > > > > -                        * multiple node types at the same time.
> > > > > > +                       /* TODO currently we don't support multiple node/coord
> > > > > > +                        * types we need to run skb_clone at rx path. Check if
> > > > > > +                        * there exist really an use case if we need to support
> > > > > > +                        * multiple node/coord types at the same time.
> > > > > >                          */
> > > > > > -                       if (wpan_dev->iftype == NL802154_IFTYPE_NODE &&
> > > > > > -                           nsdata->wpan_dev.iftype == NL802154_IFTYPE_NODE)
> > > > > > +                       if (wpan_dev->iftype != NL802154_IFTYPE_MONITOR &&
> > > > > > +                           nsdata->wpan_dev.iftype != NL802154_IFTYPE_MONITOR)
> > > > > >                                 return -EBUSY;
> > > > > >
> > > > > >                         /* check all phy mac sublayer settings are the same.
> > > > > > @@ -577,6 +577,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
> > > > > >         wpan_dev->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
> > > > > >
> > > > > >         switch (type) {
> > > > > > +       case NL802154_IFTYPE_COORD:
> > > > > >         case NL802154_IFTYPE_NODE:
> > > > > >                 ieee802154_be64_to_le64(&wpan_dev->extended_addr,
> > > > > >                                         sdata->dev->dev_addr);
> > > > > > @@ -636,6 +637,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
> > > > > >         ieee802154_le64_to_be64(ndev->perm_addr,
> > > > > >                                 &local->hw.phy->perm_extended_addr);
> > > > > >         switch (type) {
> > > > > > +       case NL802154_IFTYPE_COORD:
> > > > > >         case NL802154_IFTYPE_NODE:
> > > > > >                 ndev->type = ARPHRD_IEEE802154;
> > > > > >                 if (ieee802154_is_valid_extended_unicast_addr(extended_addr)) {
> > > > > > diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
> > > > > > index b8ce84618a55..39459d8d787a 100644
> > > > > > --- a/net/mac802154/rx.c
> > > > > > +++ b/net/mac802154/rx.c
> > > > > > @@ -203,7 +203,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > > > >         }
> > > > > >
> > > > > >         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> > > > > > -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> > > > > > +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
> > > > > >                         continue;  
> > > > >
> > > > > I probably get why you are doing that, but first the overall design is
> > > > > working differently - means you should add an additional receive path
> > > > > for the special interface type.
> > > > >
> > > > > Also we "discovered" before that the receive path of node vs
> > > > > coordinator is different... Where is the different handling here? I
> > > > > don't see it, I see that NODE and COORD are the same now (because that
> > > > > is _currently_ everything else than monitor). This change is not
> > > > > enough and does "something" to handle in some way coordinator receive
> > > > > path but there are things missing.
> > > > >
> > > > > 1. Changing the address filters that it signals the transceiver it's
> > > > > acting as coordinator
> > > > > 2. We _should_ also have additional handling for whatever the
> > > > > additional handling what address filters are doing in mac802154
> > > > > _because_ there is hardware which doesn't have address filtering e.g.
> > > > > hwsim which depend that this is working in software like other
> > > > > transceiver hardware address filters.
> > > > >
> > > > > For the 2. one, I don't know if we do that even for NODE right or we
> > > > > just have the bare minimal support there... I don't assume that
> > > > > everything is working correctly here but what I want to see is a
> > > > > separate receive path for coordinators that people can send patches to
> > > > > fix it.  
> > > >
> > > > Yes, we do very little differently between the two modes, that's why I
> > > > took the easy way: just changing the condition. I really don't see what
> > > > I can currently add here, but I am fine changing the style to easily
> > > > show people where to add filters for such or such interface, but right
> > > > now both path will look very "identical", do we agree on that?  
> > >
> > > mostly yes, but there exists a difference and we should at least check
> > > if the node receive path violates the coordinator receive path and
> > > vice versa.
> > > Put it in a receive_path() function and then coord_receive_path(),
> > > node_receive_path() that calls the receive_path() and do the
> > > additional filtering for coordinators, etc.
> > >
> > > There should be a part in the standard about "third level filter rule
> > > if it's a coordinator".
> > > btw: this is because the address filter on the transceiver needs to
> > > have the "i am a coordinator" boolean set which is missing in this
> > > series. However it depends on the transceiver filtering level and the
> > > mac802154 receive path if we actually need to run such filtering or
> > > not.  
> >
> > I must be missing some information because I can't find any places
> > where what you suggest is described in the spec.
> >
> > I agree there are multiple filtering level so let's go through them one
> > by one (6.7.2 Reception and rejection):
> > - first level: is the checksum (FCS) valid?
> >         yes -> goto second level
> >         no -> drop
> > - second level: are we in promiscuous mode?
> >         yes -> forward to upper layers
> >         no -> goto second level (bis)
> > - second level (bis): are we scanning?
> >         yes -> goto scan filtering
> >         no -> goto third level
> > - scan filtering: is it a beacon?
> >         yes -> process the beacon
> >         no -> drop
> > - third level: is the frame valid? (type, source, destination, pan id,
> >   etc)
> >         yes -> forward to upper layers
> >         no -> drop

Actually right now the second level is not enforced, and all the
filtering levels are a bit fuzzy and spread everywhere in rx.c.

I'm gonna see if I can at least clarify all of that and only make
coord-dependent the right section because right now a
ieee802154_coord_rx() path in ieee802154_rx_handle_packet() does not
really make sense given that the level 3 filtering rules are mostly
enforced in ieee802154_subif_frame().

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-24 10:20             ` Miquel Raynal
@ 2022-08-24 12:43               ` Alexander Aring
  2022-08-24 13:26                 ` Miquel Raynal
  0 siblings, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-08-24 12:43 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Wed, Aug 24, 2022 at 6:21 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
...
>
> Actually right now the second level is not enforced, and all the
> filtering levels are a bit fuzzy and spread everywhere in rx.c.
>
> I'm gonna see if I can at least clarify all of that and only make
> coord-dependent the right section because right now a
> ieee802154_coord_rx() path in ieee802154_rx_handle_packet() does not
> really make sense given that the level 3 filtering rules are mostly
> enforced in ieee802154_subif_frame().

One thing I mentioned before is that we probably like to have a
parameter for rx path to give mac802154 a hint on which filtering
level it was received. We don't have that, I currently see that this
is a parameter for hwsim receiving it on promiscuous level only and
all others do third level filtering.
We need that now, because the promiscuous mode was only used for
sniffing which goes directly into the rx path for monitors. With scan
we mix things up here and in my opinion require such a parameter and
do filtering if necessary.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-24 12:43               ` Alexander Aring
@ 2022-08-24 13:26                 ` Miquel Raynal
  2022-08-24 21:53                   ` Alexander Aring
  0 siblings, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-08-24 13:26 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Wed, 24 Aug 2022 08:43:20 -0400:

> Hi,
> 
> On Wed, Aug 24, 2022 at 6:21 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> ...
> >
> > Actually right now the second level is not enforced, and all the
> > filtering levels are a bit fuzzy and spread everywhere in rx.c.
> >
> > I'm gonna see if I can at least clarify all of that and only make
> > coord-dependent the right section because right now a
> > ieee802154_coord_rx() path in ieee802154_rx_handle_packet() does not
> > really make sense given that the level 3 filtering rules are mostly
> > enforced in ieee802154_subif_frame().  
> 
> One thing I mentioned before is that we probably like to have a
> parameter for rx path to give mac802154 a hint on which filtering
> level it was received. We don't have that, I currently see that this
> is a parameter for hwsim receiving it on promiscuous level only and
> all others do third level filtering.
> We need that now, because the promiscuous mode was only used for
> sniffing which goes directly into the rx path for monitors. With scan
> we mix things up here and in my opinion require such a parameter and
> do filtering if necessary.

I am currently trying to implement a slightly different approach. The
core does not know hwsim is always in promiscuous mode, but it does
know that it does not check FCS. So the core checks it. This is
level 1 achieved. Then in level 2 we want to know if the core asked
the transceiver to enter promiscuous mode, which, if it did, should
not imply more filtering. If the device is working in promiscuous
mode but this was not asked explicitly by the core, we don't really
care, software filtering will apply anyway.

I am reworking the rx path to clarify what is being done and when,
because I found this part very obscure right now. In the end I don't
think we need additional rx info from the drivers. Hopefully my
proposal will clarify why this is (IMHO) not needed.

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-24  7:35             ` Miquel Raynal
@ 2022-08-24 21:43               ` Alexander Aring
  2022-08-25  8:40                 ` Miquel Raynal
  0 siblings, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-08-24 21:43 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

On Wed, Aug 24, 2022 at 3:35 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> Hi Alexander,
>
> aahringo@redhat.com wrote on Tue, 23 Aug 2022 17:44:52 -0400:
>
> > Hi,
> >
> > On Tue, Aug 23, 2022 at 12:29 PM Miquel Raynal
> > <miquel.raynal@bootlin.com> wrote:
> > >
> > > Hi Alexander,
> > >
> > > aahringo@redhat.com wrote on Tue, 23 Aug 2022 08:33:30 -0400:
> > >
> > > > Hi,
> > > >
> > > > On Fri, Aug 19, 2022 at 1:11 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > > >
> > > > > Hi Alexander,
> > > > >
> > > > > aahringo@redhat.com wrote on Tue, 5 Jul 2022 21:51:02 -0400:
> > > > >
> > > > > > Hi,
> > > > > >
> > > > > > On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > > > > >
> > > > > > > As a first strep in introducing proper PAN management and association,
> > > > > > > we need to be able to create coordinator interfaces which might act as
> > > > > > > coordinator or PAN coordinator.
> > > > > > >
> > > > > > > Hence, let's add the minimum support to allow the creation of these
> > > > > > > interfaces. This might be restrained and improved later.
> > > > > > >
> > > > > > > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > > > > > > ---
> > > > > > >  net/mac802154/iface.c | 14 ++++++++------
> > > > > > >  net/mac802154/rx.c    |  2 +-
> > > > > > >  2 files changed, 9 insertions(+), 7 deletions(-)
> > > > > > >
> > > > > > > diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
> > > > > > > index 500ed1b81250..7ac0c5685d3f 100644
> > > > > > > --- a/net/mac802154/iface.c
> > > > > > > +++ b/net/mac802154/iface.c
> > > > > > > @@ -273,13 +273,13 @@ ieee802154_check_concurrent_iface(struct ieee802154_sub_if_data *sdata,
> > > > > > >                 if (nsdata != sdata && ieee802154_sdata_running(nsdata)) {
> > > > > > >                         int ret;
> > > > > > >
> > > > > > > -                       /* TODO currently we don't support multiple node types
> > > > > > > -                        * we need to run skb_clone at rx path. Check if there
> > > > > > > -                        * exist really an use case if we need to support
> > > > > > > -                        * multiple node types at the same time.
> > > > > > > +                       /* TODO currently we don't support multiple node/coord
> > > > > > > +                        * types we need to run skb_clone at rx path. Check if
> > > > > > > +                        * there exist really an use case if we need to support
> > > > > > > +                        * multiple node/coord types at the same time.
> > > > > > >                          */
> > > > > > > -                       if (wpan_dev->iftype == NL802154_IFTYPE_NODE &&
> > > > > > > -                           nsdata->wpan_dev.iftype == NL802154_IFTYPE_NODE)
> > > > > > > +                       if (wpan_dev->iftype != NL802154_IFTYPE_MONITOR &&
> > > > > > > +                           nsdata->wpan_dev.iftype != NL802154_IFTYPE_MONITOR)
> > > > > > >                                 return -EBUSY;
> > > > > > >
> > > > > > >                         /* check all phy mac sublayer settings are the same.
> > > > > > > @@ -577,6 +577,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
> > > > > > >         wpan_dev->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
> > > > > > >
> > > > > > >         switch (type) {
> > > > > > > +       case NL802154_IFTYPE_COORD:
> > > > > > >         case NL802154_IFTYPE_NODE:
> > > > > > >                 ieee802154_be64_to_le64(&wpan_dev->extended_addr,
> > > > > > >                                         sdata->dev->dev_addr);
> > > > > > > @@ -636,6 +637,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
> > > > > > >         ieee802154_le64_to_be64(ndev->perm_addr,
> > > > > > >                                 &local->hw.phy->perm_extended_addr);
> > > > > > >         switch (type) {
> > > > > > > +       case NL802154_IFTYPE_COORD:
> > > > > > >         case NL802154_IFTYPE_NODE:
> > > > > > >                 ndev->type = ARPHRD_IEEE802154;
> > > > > > >                 if (ieee802154_is_valid_extended_unicast_addr(extended_addr)) {
> > > > > > > diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
> > > > > > > index b8ce84618a55..39459d8d787a 100644
> > > > > > > --- a/net/mac802154/rx.c
> > > > > > > +++ b/net/mac802154/rx.c
> > > > > > > @@ -203,7 +203,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > > > > >         }
> > > > > > >
> > > > > > >         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> > > > > > > -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> > > > > > > +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
> > > > > > >                         continue;
> > > > > >
> > > > > > I probably get why you are doing that, but first the overall design is
> > > > > > working differently - means you should add an additional receive path
> > > > > > for the special interface type.
> > > > > >
> > > > > > Also we "discovered" before that the receive path of node vs
> > > > > > coordinator is different... Where is the different handling here? I
> > > > > > don't see it, I see that NODE and COORD are the same now (because that
> > > > > > is _currently_ everything else than monitor). This change is not
> > > > > > enough and does "something" to handle in some way coordinator receive
> > > > > > path but there are things missing.
> > > > > >
> > > > > > 1. Changing the address filters that it signals the transceiver it's
> > > > > > acting as coordinator
> > > > > > 2. We _should_ also have additional handling for whatever the
> > > > > > additional handling what address filters are doing in mac802154
> > > > > > _because_ there is hardware which doesn't have address filtering e.g.
> > > > > > hwsim which depend that this is working in software like other
> > > > > > transceiver hardware address filters.
> > > > > >
> > > > > > For the 2. one, I don't know if we do that even for NODE right or we
> > > > > > just have the bare minimal support there... I don't assume that
> > > > > > everything is working correctly here but what I want to see is a
> > > > > > separate receive path for coordinators that people can send patches to
> > > > > > fix it.
> > > > >
> > > > > Yes, we do very little differently between the two modes, that's why I
> > > > > took the easy way: just changing the condition. I really don't see what
> > > > > I can currently add here, but I am fine changing the style to easily
> > > > > show people where to add filters for such or such interface, but right
> > > > > now both path will look very "identical", do we agree on that?
> > > >
> > > > mostly yes, but there exists a difference and we should at least check
> > > > if the node receive path violates the coordinator receive path and
> > > > vice versa.
> > > > Put it in a receive_path() function and then coord_receive_path(),
> > > > node_receive_path() that calls the receive_path() and do the
> > > > additional filtering for coordinators, etc.
> > > >
> > > > There should be a part in the standard about "third level filter rule
> > > > if it's a coordinator".
> > > > btw: this is because the address filter on the transceiver needs to
> > > > have the "i am a coordinator" boolean set which is missing in this
> > > > series. However it depends on the transceiver filtering level and the
> > > > mac802154 receive path if we actually need to run such filtering or
> > > > not.
> > >
> > > I must be missing some information because I can't find any places
> > > where what you suggest is described in the spec.
> > >
> > > I agree there are multiple filtering level so let's go through them one
> > > by one (6.7.2 Reception and rejection):
> > > - first level: is the checksum (FCS) valid?
> > >         yes -> goto second level
> > >         no -> drop
> > > - second level: are we in promiscuous mode?
> > >         yes -> forward to upper layers
> > >         no -> goto second level (bis)
> > > - second level (bis): are we scanning?
> > >         yes -> goto scan filtering
> > >         no -> goto third level
> > > - scan filtering: is it a beacon?
> > >         yes -> process the beacon
> > >         no -> drop
> > > - third level: is the frame valid? (type, source, destination, pan id,
> > >   etc)
> > >         yes -> forward to upper layers
> > >         no -> drop
> > >
> > > But none of them, as you said, is dependent on the interface type.
> > > There is no mention of a specific filtering operation to do in all
> > > those cases when running in COORD mode. So I still don't get what
> > > should be included in either node_receive_path() which should be
> > > different than in coord_receive_path() for now.
> > >
> > > There are, however, two situations where the interface type has its
> > > importance:
> > > - Enhanced beacon requests with Enhanced beacon filter IE, which asks
> > >   the receiving device to process/drop the request upon certain
> > >   conditions (minimum LQI and/or randomness), as detailed in
> > >   7.4.4.6 Enhanced Beacon Filter IE. But, as mentioned in
> > >   7.5.9 Enhanced Beacon Request command: "The Enhanced Beacon Request
> > >   command is optional for an FFD and an RFD", so this series was only
> > >   targeting basic beaconing for now.
> > > - In relaying mode, the destination address must not be validated
> > >   because the message needs to be re-emitted. Indeed, a receiver in
> > >   relaying mode may not be the recipient. This is also optional and out
> > >   of the scope of this series.
> > >
> > > Right now I have the below diff, which clarifies the two path, without
> > > too much changes in the current code because I don't really see why it
> > > would be necessary. Unless you convince me otherwise or read the spec
> > > differently than I do :) What do you think?
> > >
> >
> > "Reception and rejection"
> >
> > third-level filtering regarding "destination address" and if the
> > device is "PAN coordinator".
> > This is, in my opinion, what the coordinator boolean tells the
> > transceiver to do on hardware when doing address filter there. You can
> > also read that up in datasheets of transceivers as atf86rf233, search
> > for I_AM_COORD.
>
> Oh right, I now see what you mean!
>
> > Whereas they use the word "PAN coordinator" not "coordinator", if they
> > really make a difference there at this point..., if so then the kernel
> > must know if the coordinator is a pan coordinator or coordinator
> > because we need to set the address filter in kernel.
>
> Yes we need to make a difference, you can have several coordinators but
> a single PAN coordinator in a PAN. I think we can assume that the PAN
> coordinator is the coordinator with no parent (association-wise). With
> the addition of the association series, I can handle that, so I will
> create the two path as you advise, add a comment about this additional
> filter rule that we don't yet support, and finally after the
> association series add another commit to make this filtering rule real.
>
> >
> > > Thanks,
> > > Miquèl
> > >
> > > ---
> > >
> > > --- a/net/mac802154/rx.c
> > > +++ b/net/mac802154/rx.c
> > > @@ -194,6 +194,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > >         int ret;
> > >         struct ieee802154_sub_if_data *sdata;
> > >         struct ieee802154_hdr hdr;
> > > +       bool iface_found = false;
> > >
> > >         ret = ieee802154_parse_frame_start(skb, &hdr);
> > >         if (ret) {
> > > @@ -203,18 +204,31 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > >         }
> > >
> > >         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> > > -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> > > +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
> > >                         continue;
> > >
> > >                 if (!ieee802154_sdata_running(sdata))
> > >                         continue;
> > >
> > > +               iface_found = true;
> > > +               break;
> > > +       }
> > > +
> > > +       if (!iface_found) {
> > > +               kfree_skb(skb);
> > > +               return;
> > > +       }
> > > +
> > > +       /* TBD: Additional filtering is possible on NODEs and/or COORDINATORs */
> > > +       switch (sdata->wpan_dev.iftype) {
> > > +       case NL802154_IFTYPE_COORD:
> > > +       case NL802154_IFTYPE_NODE:
> > >                 ieee802154_subif_frame(sdata, skb, &hdr);
> > > -               skb = NULL;
> > > +               break;
> > > +       default:
> > > +               kfree_skb(skb);
> > >                 break;
> > >         }
> >
> > Why do you remove the whole interface looping above and make it only
> > run for one ?first found? ?
>
> To reduce the indentation level.
>
> > That code changes this behaviour and I do
> > not know why.
>
> The precedent code did:
> for_each_iface() {
>         if (not a node)
>                 continue;
>         if (not running)
>                 continue;
>
>         subif_frame();
>         break;
> }
>
> That final break also elected only the first running node iface.
> Otherwise it would mean that we allow the same skb to be consumed
> twice, which is wrong IMHO?

no? Why is that wrong? There is a real use-case to have multiple
interfaces on one phy (or to do it in near future, I said that
multiple times). This patch does a step backwards to this.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-24 13:26                 ` Miquel Raynal
@ 2022-08-24 21:53                   ` Alexander Aring
  2022-08-25  1:02                     ` Alexander Aring
  2022-08-25 12:58                     ` Miquel Raynal
  0 siblings, 2 replies; 84+ messages in thread
From: Alexander Aring @ 2022-08-24 21:53 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Wed, Aug 24, 2022 at 9:27 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> Hi Alexander,
>
> aahringo@redhat.com wrote on Wed, 24 Aug 2022 08:43:20 -0400:
>
> > Hi,
> >
> > On Wed, Aug 24, 2022 at 6:21 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > ...
> > >
> > > Actually right now the second level is not enforced, and all the
> > > filtering levels are a bit fuzzy and spread everywhere in rx.c.
> > >
> > > I'm gonna see if I can at least clarify all of that and only make
> > > coord-dependent the right section because right now a
> > > ieee802154_coord_rx() path in ieee802154_rx_handle_packet() does not
> > > really make sense given that the level 3 filtering rules are mostly
> > > enforced in ieee802154_subif_frame().
> >
> > One thing I mentioned before is that we probably like to have a
> > parameter for rx path to give mac802154 a hint on which filtering
> > level it was received. We don't have that, I currently see that this
> > is a parameter for hwsim receiving it on promiscuous level only and
> > all others do third level filtering.
> > We need that now, because the promiscuous mode was only used for
> > sniffing which goes directly into the rx path for monitors. With scan
> > we mix things up here and in my opinion require such a parameter and
> > do filtering if necessary.
>
> I am currently trying to implement a slightly different approach. The
> core does not know hwsim is always in promiscuous mode, but it does
> know that it does not check FCS. So the core checks it. This is
> level 1 achieved. Then in level 2 we want to know if the core asked
> the transceiver to enter promiscuous mode, which, if it did, should
> not imply more filtering. If the device is working in promiscuous
> mode but this was not asked explicitly by the core, we don't really
> care, software filtering will apply anyway.
>

I doubt that I will be happy with this solution, this all sounds like
"for the specific current behaviour that we support 2 filtering levels
it will work", just do a parameter on which 802.15.4 filtering level
it was received and the rx path will check what kind of filter is
required and which not.
As driver ops start() callback you should say which filtering level
the receive mode should start with.

> I am reworking the rx path to clarify what is being done and when,
> because I found this part very obscure right now. In the end I don't
> think we need additional rx info from the drivers. Hopefully my
> proposal will clarify why this is (IMHO) not needed.
>

Never looked much in 802.15.4 receive path as it just worked but I
said that there might be things to clean up when filtering things on
hardware and when on software and I have the feeling we are doing
things twice. Sometimes it is also necessary to set some skb fields
e.g. PACKET_HOST, etc. and I think this is what the most important
part of it is there. However, there are probably some tune ups if we
know we are in third leveling filtering...

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-24 21:53                   ` Alexander Aring
@ 2022-08-25  1:02                     ` Alexander Aring
  2022-08-25  8:46                       ` Miquel Raynal
  2022-08-25 12:58                     ` Miquel Raynal
  1 sibling, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-08-25  1:02 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Wed, Aug 24, 2022 at 5:53 PM Alexander Aring <aahringo@redhat.com> wrote:
>
> Hi,
>
> On Wed, Aug 24, 2022 at 9:27 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> >
> > Hi Alexander,
> >
> > aahringo@redhat.com wrote on Wed, 24 Aug 2022 08:43:20 -0400:
> >
> > > Hi,
> > >
> > > On Wed, Aug 24, 2022 at 6:21 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > ...
> > > >
> > > > Actually right now the second level is not enforced, and all the
> > > > filtering levels are a bit fuzzy and spread everywhere in rx.c.
> > > >
> > > > I'm gonna see if I can at least clarify all of that and only make
> > > > coord-dependent the right section because right now a
> > > > ieee802154_coord_rx() path in ieee802154_rx_handle_packet() does not
> > > > really make sense given that the level 3 filtering rules are mostly
> > > > enforced in ieee802154_subif_frame().
> > >
> > > One thing I mentioned before is that we probably like to have a
> > > parameter for rx path to give mac802154 a hint on which filtering
> > > level it was received. We don't have that, I currently see that this
> > > is a parameter for hwsim receiving it on promiscuous level only and
> > > all others do third level filtering.
> > > We need that now, because the promiscuous mode was only used for
> > > sniffing which goes directly into the rx path for monitors. With scan
> > > we mix things up here and in my opinion require such a parameter and
> > > do filtering if necessary.
> >
> > I am currently trying to implement a slightly different approach. The
> > core does not know hwsim is always in promiscuous mode, but it does
> > know that it does not check FCS. So the core checks it. This is
> > level 1 achieved. Then in level 2 we want to know if the core asked
> > the transceiver to enter promiscuous mode, which, if it did, should
> > not imply more filtering. If the device is working in promiscuous
> > mode but this was not asked explicitly by the core, we don't really
> > care, software filtering will apply anyway.
> >
>
> I doubt that I will be happy with this solution, this all sounds like
> "for the specific current behaviour that we support 2 filtering levels
> it will work", just do a parameter on which 802.15.4 filtering level
> it was received and the rx path will check what kind of filter is

I think a per phy field is enough here because the receive path should
be synchronized with changing filtering level on hardware. No need for
per receive path parameter.

"If the device is working in promiscuous mode but this was not asked
explicitly by the core, we don't really care, software filtering will
apply anyway."
I don't understand this sentence, we should not filter on things which
the hardware is doing for us. I mean okay I'm fine to handle it now
just to check twice, but in the future there might be more "we don't
need to filter this because we know the hardware is doing it" patches.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-24 21:43               ` Alexander Aring
@ 2022-08-25  8:40                 ` Miquel Raynal
  2022-08-26  0:51                   ` Alexander Aring
  0 siblings, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-08-25  8:40 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Wed, 24 Aug 2022 17:43:11 -0400:

> On Wed, Aug 24, 2022 at 3:35 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> >
> > Hi Alexander,
> >
> > aahringo@redhat.com wrote on Tue, 23 Aug 2022 17:44:52 -0400:
> >  
> > > Hi,
> > >
> > > On Tue, Aug 23, 2022 at 12:29 PM Miquel Raynal
> > > <miquel.raynal@bootlin.com> wrote:  
> > > >
> > > > Hi Alexander,
> > > >
> > > > aahringo@redhat.com wrote on Tue, 23 Aug 2022 08:33:30 -0400:
> > > >  
> > > > > Hi,
> > > > >
> > > > > On Fri, Aug 19, 2022 at 1:11 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > > > > >
> > > > > > Hi Alexander,
> > > > > >
> > > > > > aahringo@redhat.com wrote on Tue, 5 Jul 2022 21:51:02 -0400:
> > > > > >  
> > > > > > > Hi,
> > > > > > >
> > > > > > > On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > > > > > > >
> > > > > > > > As a first strep in introducing proper PAN management and association,
> > > > > > > > we need to be able to create coordinator interfaces which might act as
> > > > > > > > coordinator or PAN coordinator.
> > > > > > > >
> > > > > > > > Hence, let's add the minimum support to allow the creation of these
> > > > > > > > interfaces. This might be restrained and improved later.
> > > > > > > >
> > > > > > > > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > > > > > > > ---
> > > > > > > >  net/mac802154/iface.c | 14 ++++++++------
> > > > > > > >  net/mac802154/rx.c    |  2 +-
> > > > > > > >  2 files changed, 9 insertions(+), 7 deletions(-)
> > > > > > > >
> > > > > > > > diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
> > > > > > > > index 500ed1b81250..7ac0c5685d3f 100644
> > > > > > > > --- a/net/mac802154/iface.c
> > > > > > > > +++ b/net/mac802154/iface.c
> > > > > > > > @@ -273,13 +273,13 @@ ieee802154_check_concurrent_iface(struct ieee802154_sub_if_data *sdata,
> > > > > > > >                 if (nsdata != sdata && ieee802154_sdata_running(nsdata)) {
> > > > > > > >                         int ret;
> > > > > > > >
> > > > > > > > -                       /* TODO currently we don't support multiple node types
> > > > > > > > -                        * we need to run skb_clone at rx path. Check if there
> > > > > > > > -                        * exist really an use case if we need to support
> > > > > > > > -                        * multiple node types at the same time.
> > > > > > > > +                       /* TODO currently we don't support multiple node/coord
> > > > > > > > +                        * types we need to run skb_clone at rx path. Check if
> > > > > > > > +                        * there exist really an use case if we need to support
> > > > > > > > +                        * multiple node/coord types at the same time.
> > > > > > > >                          */
> > > > > > > > -                       if (wpan_dev->iftype == NL802154_IFTYPE_NODE &&
> > > > > > > > -                           nsdata->wpan_dev.iftype == NL802154_IFTYPE_NODE)
> > > > > > > > +                       if (wpan_dev->iftype != NL802154_IFTYPE_MONITOR &&
> > > > > > > > +                           nsdata->wpan_dev.iftype != NL802154_IFTYPE_MONITOR)
> > > > > > > >                                 return -EBUSY;
> > > > > > > >
> > > > > > > >                         /* check all phy mac sublayer settings are the same.
> > > > > > > > @@ -577,6 +577,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
> > > > > > > >         wpan_dev->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
> > > > > > > >
> > > > > > > >         switch (type) {
> > > > > > > > +       case NL802154_IFTYPE_COORD:
> > > > > > > >         case NL802154_IFTYPE_NODE:
> > > > > > > >                 ieee802154_be64_to_le64(&wpan_dev->extended_addr,
> > > > > > > >                                         sdata->dev->dev_addr);
> > > > > > > > @@ -636,6 +637,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
> > > > > > > >         ieee802154_le64_to_be64(ndev->perm_addr,
> > > > > > > >                                 &local->hw.phy->perm_extended_addr);
> > > > > > > >         switch (type) {
> > > > > > > > +       case NL802154_IFTYPE_COORD:
> > > > > > > >         case NL802154_IFTYPE_NODE:
> > > > > > > >                 ndev->type = ARPHRD_IEEE802154;
> > > > > > > >                 if (ieee802154_is_valid_extended_unicast_addr(extended_addr)) {
> > > > > > > > diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
> > > > > > > > index b8ce84618a55..39459d8d787a 100644
> > > > > > > > --- a/net/mac802154/rx.c
> > > > > > > > +++ b/net/mac802154/rx.c
> > > > > > > > @@ -203,7 +203,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > > > > > >         }
> > > > > > > >
> > > > > > > >         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> > > > > > > > -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> > > > > > > > +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
> > > > > > > >                         continue;  
> > > > > > >
> > > > > > > I probably get why you are doing that, but first the overall design is
> > > > > > > working differently - means you should add an additional receive path
> > > > > > > for the special interface type.
> > > > > > >
> > > > > > > Also we "discovered" before that the receive path of node vs
> > > > > > > coordinator is different... Where is the different handling here? I
> > > > > > > don't see it, I see that NODE and COORD are the same now (because that
> > > > > > > is _currently_ everything else than monitor). This change is not
> > > > > > > enough and does "something" to handle in some way coordinator receive
> > > > > > > path but there are things missing.
> > > > > > >
> > > > > > > 1. Changing the address filters that it signals the transceiver it's
> > > > > > > acting as coordinator
> > > > > > > 2. We _should_ also have additional handling for whatever the
> > > > > > > additional handling what address filters are doing in mac802154
> > > > > > > _because_ there is hardware which doesn't have address filtering e.g.
> > > > > > > hwsim which depend that this is working in software like other
> > > > > > > transceiver hardware address filters.
> > > > > > >
> > > > > > > For the 2. one, I don't know if we do that even for NODE right or we
> > > > > > > just have the bare minimal support there... I don't assume that
> > > > > > > everything is working correctly here but what I want to see is a
> > > > > > > separate receive path for coordinators that people can send patches to
> > > > > > > fix it.  
> > > > > >
> > > > > > Yes, we do very little differently between the two modes, that's why I
> > > > > > took the easy way: just changing the condition. I really don't see what
> > > > > > I can currently add here, but I am fine changing the style to easily
> > > > > > show people where to add filters for such or such interface, but right
> > > > > > now both path will look very "identical", do we agree on that?  
> > > > >
> > > > > mostly yes, but there exists a difference and we should at least check
> > > > > if the node receive path violates the coordinator receive path and
> > > > > vice versa.
> > > > > Put it in a receive_path() function and then coord_receive_path(),
> > > > > node_receive_path() that calls the receive_path() and do the
> > > > > additional filtering for coordinators, etc.
> > > > >
> > > > > There should be a part in the standard about "third level filter rule
> > > > > if it's a coordinator".
> > > > > btw: this is because the address filter on the transceiver needs to
> > > > > have the "i am a coordinator" boolean set which is missing in this
> > > > > series. However it depends on the transceiver filtering level and the
> > > > > mac802154 receive path if we actually need to run such filtering or
> > > > > not.  
> > > >
> > > > I must be missing some information because I can't find any places
> > > > where what you suggest is described in the spec.
> > > >
> > > > I agree there are multiple filtering level so let's go through them one
> > > > by one (6.7.2 Reception and rejection):
> > > > - first level: is the checksum (FCS) valid?
> > > >         yes -> goto second level
> > > >         no -> drop
> > > > - second level: are we in promiscuous mode?
> > > >         yes -> forward to upper layers
> > > >         no -> goto second level (bis)
> > > > - second level (bis): are we scanning?
> > > >         yes -> goto scan filtering
> > > >         no -> goto third level
> > > > - scan filtering: is it a beacon?
> > > >         yes -> process the beacon
> > > >         no -> drop
> > > > - third level: is the frame valid? (type, source, destination, pan id,
> > > >   etc)
> > > >         yes -> forward to upper layers
> > > >         no -> drop
> > > >
> > > > But none of them, as you said, is dependent on the interface type.
> > > > There is no mention of a specific filtering operation to do in all
> > > > those cases when running in COORD mode. So I still don't get what
> > > > should be included in either node_receive_path() which should be
> > > > different than in coord_receive_path() for now.
> > > >
> > > > There are, however, two situations where the interface type has its
> > > > importance:
> > > > - Enhanced beacon requests with Enhanced beacon filter IE, which asks
> > > >   the receiving device to process/drop the request upon certain
> > > >   conditions (minimum LQI and/or randomness), as detailed in
> > > >   7.4.4.6 Enhanced Beacon Filter IE. But, as mentioned in
> > > >   7.5.9 Enhanced Beacon Request command: "The Enhanced Beacon Request
> > > >   command is optional for an FFD and an RFD", so this series was only
> > > >   targeting basic beaconing for now.
> > > > - In relaying mode, the destination address must not be validated
> > > >   because the message needs to be re-emitted. Indeed, a receiver in
> > > >   relaying mode may not be the recipient. This is also optional and out
> > > >   of the scope of this series.
> > > >
> > > > Right now I have the below diff, which clarifies the two path, without
> > > > too much changes in the current code because I don't really see why it
> > > > would be necessary. Unless you convince me otherwise or read the spec
> > > > differently than I do :) What do you think?
> > > >  
> > >
> > > "Reception and rejection"
> > >
> > > third-level filtering regarding "destination address" and if the
> > > device is "PAN coordinator".
> > > This is, in my opinion, what the coordinator boolean tells the
> > > transceiver to do on hardware when doing address filter there. You can
> > > also read that up in datasheets of transceivers as atf86rf233, search
> > > for I_AM_COORD.  
> >
> > Oh right, I now see what you mean!
> >  
> > > Whereas they use the word "PAN coordinator" not "coordinator", if they
> > > really make a difference there at this point..., if so then the kernel
> > > must know if the coordinator is a pan coordinator or coordinator
> > > because we need to set the address filter in kernel.  
> >
> > Yes we need to make a difference, you can have several coordinators but
> > a single PAN coordinator in a PAN. I think we can assume that the PAN
> > coordinator is the coordinator with no parent (association-wise). With
> > the addition of the association series, I can handle that, so I will
> > create the two path as you advise, add a comment about this additional
> > filter rule that we don't yet support, and finally after the
> > association series add another commit to make this filtering rule real.
> >  
> > >  
> > > > Thanks,
> > > > Miquèl
> > > >
> > > > ---
> > > >
> > > > --- a/net/mac802154/rx.c
> > > > +++ b/net/mac802154/rx.c
> > > > @@ -194,6 +194,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > >         int ret;
> > > >         struct ieee802154_sub_if_data *sdata;
> > > >         struct ieee802154_hdr hdr;
> > > > +       bool iface_found = false;
> > > >
> > > >         ret = ieee802154_parse_frame_start(skb, &hdr);
> > > >         if (ret) {
> > > > @@ -203,18 +204,31 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > >         }
> > > >
> > > >         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> > > > -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> > > > +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
> > > >                         continue;
> > > >
> > > >                 if (!ieee802154_sdata_running(sdata))
> > > >                         continue;
> > > >
> > > > +               iface_found = true;
> > > > +               break;
> > > > +       }
> > > > +
> > > > +       if (!iface_found) {
> > > > +               kfree_skb(skb);
> > > > +               return;
> > > > +       }
> > > > +
> > > > +       /* TBD: Additional filtering is possible on NODEs and/or COORDINATORs */
> > > > +       switch (sdata->wpan_dev.iftype) {
> > > > +       case NL802154_IFTYPE_COORD:
> > > > +       case NL802154_IFTYPE_NODE:
> > > >                 ieee802154_subif_frame(sdata, skb, &hdr);
> > > > -               skb = NULL;
> > > > +               break;
> > > > +       default:
> > > > +               kfree_skb(skb);
> > > >                 break;
> > > >         }  
> > >
> > > Why do you remove the whole interface looping above and make it only
> > > run for one ?first found? ?  
> >
> > To reduce the indentation level.
> >  
> > > That code changes this behaviour and I do
> > > not know why.  
> >
> > The precedent code did:
> > for_each_iface() {
> >         if (not a node)
> >                 continue;
> >         if (not running)
> >                 continue;
> >
> >         subif_frame();
> >         break;
> > }
> >
> > That final break also elected only the first running node iface.
> > Otherwise it would mean that we allow the same skb to be consumed
> > twice, which is wrong IMHO?  
> 
> no? Why is that wrong? There is a real use-case to have multiple
> interfaces on one phy (or to do it in near future, I said that
> multiple times). This patch does a step backwards to this.

So we need to duplicate the skb because it automatically gets freed in
the "forward to upper layer" path. Am I right? I'm fine doing so if
this is the way to go, but I am interested if you can give me a real
use case where having NODE+COORDINATOR on the same PHY is useful?

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-25  1:02                     ` Alexander Aring
@ 2022-08-25  8:46                       ` Miquel Raynal
  0 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-08-25  8:46 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Wed, 24 Aug 2022 21:02:29 -0400:

> Hi,
> 
> On Wed, Aug 24, 2022 at 5:53 PM Alexander Aring <aahringo@redhat.com> wrote:
> >
> > Hi,
> >
> > On Wed, Aug 24, 2022 at 9:27 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > >
> > > Hi Alexander,
> > >
> > > aahringo@redhat.com wrote on Wed, 24 Aug 2022 08:43:20 -0400:
> > >  
> > > > Hi,
> > > >
> > > > On Wed, Aug 24, 2022 at 6:21 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > > ...  
> > > > >
> > > > > Actually right now the second level is not enforced, and all the
> > > > > filtering levels are a bit fuzzy and spread everywhere in rx.c.
> > > > >
> > > > > I'm gonna see if I can at least clarify all of that and only make
> > > > > coord-dependent the right section because right now a
> > > > > ieee802154_coord_rx() path in ieee802154_rx_handle_packet() does not
> > > > > really make sense given that the level 3 filtering rules are mostly
> > > > > enforced in ieee802154_subif_frame().  
> > > >
> > > > One thing I mentioned before is that we probably like to have a
> > > > parameter for rx path to give mac802154 a hint on which filtering
> > > > level it was received. We don't have that, I currently see that this
> > > > is a parameter for hwsim receiving it on promiscuous level only and
> > > > all others do third level filtering.
> > > > We need that now, because the promiscuous mode was only used for
> > > > sniffing which goes directly into the rx path for monitors. With scan
> > > > we mix things up here and in my opinion require such a parameter and
> > > > do filtering if necessary.  
> > >
> > > I am currently trying to implement a slightly different approach. The
> > > core does not know hwsim is always in promiscuous mode, but it does
> > > know that it does not check FCS. So the core checks it. This is
> > > level 1 achieved. Then in level 2 we want to know if the core asked
> > > the transceiver to enter promiscuous mode, which, if it did, should
> > > not imply more filtering. If the device is working in promiscuous
> > > mode but this was not asked explicitly by the core, we don't really
> > > care, software filtering will apply anyway.
> > >  
> >
> > I doubt that I will be happy with this solution, this all sounds like
> > "for the specific current behaviour that we support 2 filtering levels
> > it will work", just do a parameter on which 802.15.4 filtering level
> > it was received and the rx path will check what kind of filter is  
> 
> I think a per phy field is enough here because the receive path should
> be synchronized with changing filtering level on hardware. No need for
> per receive path parameter.

Ok, I prefer the per-PHY field rather than the per-received-skb info.

I will add a parameter in the start field set to LEVEL3, drivers are
free to change this (like hwsim) if they can't.

I will add also the major filtering rules in the rx path but we will
actually use them only if the hw filtering level is lower than what is
requested, as you said.

> 
> "If the device is working in promiscuous mode but this was not asked
> explicitly by the core, we don't really care, software filtering will
> apply anyway."
> I don't understand this sentence, we should not filter on things which
> the hardware is doing for us. I mean okay I'm fine to handle it now
> just to check twice, but in the future there might be more "we don't
> need to filter this because we know the hardware is doing it" patches.
> 
> - Alex
> 


Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-24 21:53                   ` Alexander Aring
  2022-08-25  1:02                     ` Alexander Aring
@ 2022-08-25 12:58                     ` Miquel Raynal
  2022-08-26  1:05                       ` Alexander Aring
  1 sibling, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-08-25 12:58 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Wed, 24 Aug 2022 17:53:45 -0400:

> Hi,
> 
> On Wed, Aug 24, 2022 at 9:27 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> >
> > Hi Alexander,
> >
> > aahringo@redhat.com wrote on Wed, 24 Aug 2022 08:43:20 -0400:
> >  
> > > Hi,
> > >
> > > On Wed, Aug 24, 2022 at 6:21 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > ...  
> > > >
> > > > Actually right now the second level is not enforced, and all the
> > > > filtering levels are a bit fuzzy and spread everywhere in rx.c.
> > > >
> > > > I'm gonna see if I can at least clarify all of that and only make
> > > > coord-dependent the right section because right now a
> > > > ieee802154_coord_rx() path in ieee802154_rx_handle_packet() does not
> > > > really make sense given that the level 3 filtering rules are mostly
> > > > enforced in ieee802154_subif_frame().  
> > >
> > > One thing I mentioned before is that we probably like to have a
> > > parameter for rx path to give mac802154 a hint on which filtering
> > > level it was received. We don't have that, I currently see that this
> > > is a parameter for hwsim receiving it on promiscuous level only and
> > > all others do third level filtering.
> > > We need that now, because the promiscuous mode was only used for
> > > sniffing which goes directly into the rx path for monitors. With scan
> > > we mix things up here and in my opinion require such a parameter and
> > > do filtering if necessary.  
> >
> > I am currently trying to implement a slightly different approach. The
> > core does not know hwsim is always in promiscuous mode, but it does
> > know that it does not check FCS. So the core checks it. This is
> > level 1 achieved. Then in level 2 we want to know if the core asked
> > the transceiver to enter promiscuous mode, which, if it did, should
> > not imply more filtering. If the device is working in promiscuous
> > mode but this was not asked explicitly by the core, we don't really
> > care, software filtering will apply anyway.
> >  
> 
> I doubt that I will be happy with this solution, this all sounds like
> "for the specific current behaviour that we support 2 filtering levels
> it will work", just do a parameter on which 802.15.4 filtering level
> it was received and the rx path will check what kind of filter is
> required and which not.
> As driver ops start() callback you should say which filtering level
> the receive mode should start with.
> 
> > I am reworking the rx path to clarify what is being done and when,
> > because I found this part very obscure right now. In the end I don't
> > think we need additional rx info from the drivers. Hopefully my
> > proposal will clarify why this is (IMHO) not needed.
> >  
> 
> Never looked much in 802.15.4 receive path as it just worked but I
> said that there might be things to clean up when filtering things on
> hardware and when on software and I have the feeling we are doing
> things twice. Sometimes it is also necessary to set some skb fields
> e.g. PACKET_HOST, etc. and I think this is what the most important
> part of it is there. However, there are probably some tune ups if we
> know we are in third leveling filtering...

Ok, I've done the following.

- Adding a PHY parameter which reflects the actual filtering level of
  the transceiver, the default level is 4 (standard situation, you're
  receiving data) but of course if the PHY does not support this state
  (like hwsim) it should overwrite this value by setting the actual
  filtering level (none, in the hwsim case) so that the core knows what
  it receives.

- I've replaced the specific "do not check the FCS" flag only used by
  hwsim by this filtering level, which gives all the information we
  need.

- I've added a real promiscuous filtering mode which truly does not
  care about the content of the frame but only checks the FCS if not
  already done by the xceiver.

- I've also implemented in software filtering level 4 for most regular
  data packets. Without changing the default PHY level mentioned in the
  first item above, this additional filtering will be skipped which
  ensures we keep the same behavior of most driver. In the case of hwsim
  however, these filters will become active if the MAC is not in
  promiscuous mode or in scan mode, which is actually what people
  should be expecting.

Hopefully all this fits what you had in mind.

I have one item left on my current todo list: improving a bit the
userspace tool with a "monitor" command.

Otherwise the remaining things to do are to discuss the locking design
which might need to be changed to avoid lockdep issues and keep the
rtnl locked eg. during a channel change. I still don't know how to do
that, so it's likely that the right next version will not include any
change in this area unless something pops up.

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 19/20] ieee802154: hwsim: Do not check the rtnl
  2022-08-19 17:09     ` Miquel Raynal
@ 2022-08-25 22:41       ` Miquel Raynal
  0 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-08-25 22:41 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

miquel.raynal@bootlin.com wrote on Fri, 19 Aug 2022 19:09:44 +0200:

> Hi Alexander,
> 
> aahringo@redhat.com wrote on Tue, 5 Jul 2022 21:23:21 -0400:
> 
> > Hi,
> > 
> > On Fri, Jul 1, 2022 at 10:37 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > >
> > > There is no need to ensure the rtnl is locked when changing a driver's
> > > channel. This cause issues when scanning and this is the only driver
> > > relying on it. Just drop this dependency because it does not seem
> > > legitimate.
> > >    
> > 
> > switching channels relies on changing pib attributes, pib attributes
> > are protected by rtnl. If you experience issues here then it's
> > probably because you do something wrong. All drivers assuming here
> > that rtnl lock is held.  
> 
> ---8<---
> > especially this change could end in invalid free. Maybe we can solve
> > this problem in a different way, what exactly is the problem by
> > helding rtnl lock?
> --->8---  
> 
> During a scan we need to change channels. So when the background job
> kicks-in, we first acquire scan_lock, then we check the internal
> parameters of the structure protected by this lock, like the next
> channel to use and the sdata pointer. A channel change must be
> performed, preceded by an rtnl_lock(). This will again trigger a
> possible circular lockdep dependency warning because the triggering path
> acquires the rtnl (as part of the netlink layer) before the scan lock.
> 
> One possible solution would be to do the following:
> scan_work() {
> 	acquire(scan_lock);
> 	// do some config
> 	release(scan_lock);
> 	rtnl_lock();
> 	perform_channel_change();
> 	rtnl_unlock();
> 	acquire(scan_lock);
> 	// reinit the scan struct ptr and the sdata ptr
> 	// do some more things
> 	release(scan_lock);
> }
> 
> It looks highly non-elegant IMHO. Otherwise I need to stop verifying in
> the drivers that the rtnl is taken. Any third option here?

I've tried two other solutions.

A/ Enforcing the dependency rtnl -> scan_lock

This means always acquiring the rtnl before scan_lock, and in terms of
code requires to take the rtnl in the scan worker. Of course enclosing
the drv_change_chan() call would mean releasing the scan_lock in the
middle and re-taking it after all, which would defeat the protection of
the scan_req structure which the lock is supposed to enforce. So I went
for acquiring the lock at the top, before acquiring scan_lock, of
course.

This does not work because we need to acquire the rtnl in the worker,
while at the same time there are places like ->slave_close which need
to acquire the worker lock (during flush_workqueue()) and this can only
happen under rtnl. Lockdep then complains about a possible circular
dependency.

B/ Avoiding the rtnl in scan operations and allowing the reverse
dependency, which is scan_lock -> rtnl

I've drafted this solution because I think the scan operation do not
really need the rtnl. This idea got reinforced when I found this
wireless change: a05829a7222e ("cfg80211: avoid holding the RTNL when
calling the driver").

But unfortunately I get the same issue again, with the ->close()
implementation which needs to acquire the worker lock to flush, this
makes a rtnl -> worker_lock dependency which is incompatible with a
worker_lock -> scan_lock -> rtnl chain (this is is typically what should
happen when changing the channel during a scan).

So I looked at reducing the scope of scan_lock, in order to avoid
taking it for too long and avoid the scan_lock -> rtnl or rtnl ->
scan_lock dependency in the worker, but I think in the end it is a
truly bad idea.

Finally, I decided I could use another workqueue for the mac related
commands which is not the one for the data. We don't care about
flushing it because we _need_ the beacons/scan workers to be stopped,
which is handled in their dedicated helpers. Doing so removes a rtnl ->
worker_lock dependency, which allows to acquire the rtnl from the
worker. I've mostly implemented it, I'll clean all this up and send a
v2 tomorrow.

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-25  8:40                 ` Miquel Raynal
@ 2022-08-26  0:51                   ` Alexander Aring
  2022-08-26  1:35                     ` Alexander Aring
  2022-08-26  7:30                     ` Miquel Raynal
  0 siblings, 2 replies; 84+ messages in thread
From: Alexander Aring @ 2022-08-26  0:51 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Thu, Aug 25, 2022 at 4:41 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> Hi Alexander,
>
> aahringo@redhat.com wrote on Wed, 24 Aug 2022 17:43:11 -0400:
>
> > On Wed, Aug 24, 2022 at 3:35 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > >
> > > Hi Alexander,
> > >
> > > aahringo@redhat.com wrote on Tue, 23 Aug 2022 17:44:52 -0400:
> > >
> > > > Hi,
> > > >
> > > > On Tue, Aug 23, 2022 at 12:29 PM Miquel Raynal
> > > > <miquel.raynal@bootlin.com> wrote:
> > > > >
> > > > > Hi Alexander,
> > > > >
> > > > > aahringo@redhat.com wrote on Tue, 23 Aug 2022 08:33:30 -0400:
> > > > >
> > > > > > Hi,
> > > > > >
> > > > > > On Fri, Aug 19, 2022 at 1:11 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > > > > >
> > > > > > > Hi Alexander,
> > > > > > >
> > > > > > > aahringo@redhat.com wrote on Tue, 5 Jul 2022 21:51:02 -0400:
> > > > > > >
> > > > > > > > Hi,
> > > > > > > >
> > > > > > > > On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > > > > > > >
> > > > > > > > > As a first strep in introducing proper PAN management and association,
> > > > > > > > > we need to be able to create coordinator interfaces which might act as
> > > > > > > > > coordinator or PAN coordinator.
> > > > > > > > >
> > > > > > > > > Hence, let's add the minimum support to allow the creation of these
> > > > > > > > > interfaces. This might be restrained and improved later.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > > > > > > > > ---
> > > > > > > > >  net/mac802154/iface.c | 14 ++++++++------
> > > > > > > > >  net/mac802154/rx.c    |  2 +-
> > > > > > > > >  2 files changed, 9 insertions(+), 7 deletions(-)
> > > > > > > > >
> > > > > > > > > diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
> > > > > > > > > index 500ed1b81250..7ac0c5685d3f 100644
> > > > > > > > > --- a/net/mac802154/iface.c
> > > > > > > > > +++ b/net/mac802154/iface.c
> > > > > > > > > @@ -273,13 +273,13 @@ ieee802154_check_concurrent_iface(struct ieee802154_sub_if_data *sdata,
> > > > > > > > >                 if (nsdata != sdata && ieee802154_sdata_running(nsdata)) {
> > > > > > > > >                         int ret;
> > > > > > > > >
> > > > > > > > > -                       /* TODO currently we don't support multiple node types
> > > > > > > > > -                        * we need to run skb_clone at rx path. Check if there
> > > > > > > > > -                        * exist really an use case if we need to support
> > > > > > > > > -                        * multiple node types at the same time.
> > > > > > > > > +                       /* TODO currently we don't support multiple node/coord
> > > > > > > > > +                        * types we need to run skb_clone at rx path. Check if
> > > > > > > > > +                        * there exist really an use case if we need to support
> > > > > > > > > +                        * multiple node/coord types at the same time.
> > > > > > > > >                          */
> > > > > > > > > -                       if (wpan_dev->iftype == NL802154_IFTYPE_NODE &&
> > > > > > > > > -                           nsdata->wpan_dev.iftype == NL802154_IFTYPE_NODE)
> > > > > > > > > +                       if (wpan_dev->iftype != NL802154_IFTYPE_MONITOR &&
> > > > > > > > > +                           nsdata->wpan_dev.iftype != NL802154_IFTYPE_MONITOR)
> > > > > > > > >                                 return -EBUSY;
> > > > > > > > >
> > > > > > > > >                         /* check all phy mac sublayer settings are the same.
> > > > > > > > > @@ -577,6 +577,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
> > > > > > > > >         wpan_dev->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
> > > > > > > > >
> > > > > > > > >         switch (type) {
> > > > > > > > > +       case NL802154_IFTYPE_COORD:
> > > > > > > > >         case NL802154_IFTYPE_NODE:
> > > > > > > > >                 ieee802154_be64_to_le64(&wpan_dev->extended_addr,
> > > > > > > > >                                         sdata->dev->dev_addr);
> > > > > > > > > @@ -636,6 +637,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
> > > > > > > > >         ieee802154_le64_to_be64(ndev->perm_addr,
> > > > > > > > >                                 &local->hw.phy->perm_extended_addr);
> > > > > > > > >         switch (type) {
> > > > > > > > > +       case NL802154_IFTYPE_COORD:
> > > > > > > > >         case NL802154_IFTYPE_NODE:
> > > > > > > > >                 ndev->type = ARPHRD_IEEE802154;
> > > > > > > > >                 if (ieee802154_is_valid_extended_unicast_addr(extended_addr)) {
> > > > > > > > > diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
> > > > > > > > > index b8ce84618a55..39459d8d787a 100644
> > > > > > > > > --- a/net/mac802154/rx.c
> > > > > > > > > +++ b/net/mac802154/rx.c
> > > > > > > > > @@ -203,7 +203,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > > > > > > >         }
> > > > > > > > >
> > > > > > > > >         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> > > > > > > > > -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> > > > > > > > > +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
> > > > > > > > >                         continue;
> > > > > > > >
> > > > > > > > I probably get why you are doing that, but first the overall design is
> > > > > > > > working differently - means you should add an additional receive path
> > > > > > > > for the special interface type.
> > > > > > > >
> > > > > > > > Also we "discovered" before that the receive path of node vs
> > > > > > > > coordinator is different... Where is the different handling here? I
> > > > > > > > don't see it, I see that NODE and COORD are the same now (because that
> > > > > > > > is _currently_ everything else than monitor). This change is not
> > > > > > > > enough and does "something" to handle in some way coordinator receive
> > > > > > > > path but there are things missing.
> > > > > > > >
> > > > > > > > 1. Changing the address filters that it signals the transceiver it's
> > > > > > > > acting as coordinator
> > > > > > > > 2. We _should_ also have additional handling for whatever the
> > > > > > > > additional handling what address filters are doing in mac802154
> > > > > > > > _because_ there is hardware which doesn't have address filtering e.g.
> > > > > > > > hwsim which depend that this is working in software like other
> > > > > > > > transceiver hardware address filters.
> > > > > > > >
> > > > > > > > For the 2. one, I don't know if we do that even for NODE right or we
> > > > > > > > just have the bare minimal support there... I don't assume that
> > > > > > > > everything is working correctly here but what I want to see is a
> > > > > > > > separate receive path for coordinators that people can send patches to
> > > > > > > > fix it.
> > > > > > >
> > > > > > > Yes, we do very little differently between the two modes, that's why I
> > > > > > > took the easy way: just changing the condition. I really don't see what
> > > > > > > I can currently add here, but I am fine changing the style to easily
> > > > > > > show people where to add filters for such or such interface, but right
> > > > > > > now both path will look very "identical", do we agree on that?
> > > > > >
> > > > > > mostly yes, but there exists a difference and we should at least check
> > > > > > if the node receive path violates the coordinator receive path and
> > > > > > vice versa.
> > > > > > Put it in a receive_path() function and then coord_receive_path(),
> > > > > > node_receive_path() that calls the receive_path() and do the
> > > > > > additional filtering for coordinators, etc.
> > > > > >
> > > > > > There should be a part in the standard about "third level filter rule
> > > > > > if it's a coordinator".
> > > > > > btw: this is because the address filter on the transceiver needs to
> > > > > > have the "i am a coordinator" boolean set which is missing in this
> > > > > > series. However it depends on the transceiver filtering level and the
> > > > > > mac802154 receive path if we actually need to run such filtering or
> > > > > > not.
> > > > >
> > > > > I must be missing some information because I can't find any places
> > > > > where what you suggest is described in the spec.
> > > > >
> > > > > I agree there are multiple filtering level so let's go through them one
> > > > > by one (6.7.2 Reception and rejection):
> > > > > - first level: is the checksum (FCS) valid?
> > > > >         yes -> goto second level
> > > > >         no -> drop
> > > > > - second level: are we in promiscuous mode?
> > > > >         yes -> forward to upper layers
> > > > >         no -> goto second level (bis)
> > > > > - second level (bis): are we scanning?
> > > > >         yes -> goto scan filtering
> > > > >         no -> goto third level
> > > > > - scan filtering: is it a beacon?
> > > > >         yes -> process the beacon
> > > > >         no -> drop
> > > > > - third level: is the frame valid? (type, source, destination, pan id,
> > > > >   etc)
> > > > >         yes -> forward to upper layers
> > > > >         no -> drop
> > > > >
> > > > > But none of them, as you said, is dependent on the interface type.
> > > > > There is no mention of a specific filtering operation to do in all
> > > > > those cases when running in COORD mode. So I still don't get what
> > > > > should be included in either node_receive_path() which should be
> > > > > different than in coord_receive_path() for now.
> > > > >
> > > > > There are, however, two situations where the interface type has its
> > > > > importance:
> > > > > - Enhanced beacon requests with Enhanced beacon filter IE, which asks
> > > > >   the receiving device to process/drop the request upon certain
> > > > >   conditions (minimum LQI and/or randomness), as detailed in
> > > > >   7.4.4.6 Enhanced Beacon Filter IE. But, as mentioned in
> > > > >   7.5.9 Enhanced Beacon Request command: "The Enhanced Beacon Request
> > > > >   command is optional for an FFD and an RFD", so this series was only
> > > > >   targeting basic beaconing for now.
> > > > > - In relaying mode, the destination address must not be validated
> > > > >   because the message needs to be re-emitted. Indeed, a receiver in
> > > > >   relaying mode may not be the recipient. This is also optional and out
> > > > >   of the scope of this series.
> > > > >
> > > > > Right now I have the below diff, which clarifies the two path, without
> > > > > too much changes in the current code because I don't really see why it
> > > > > would be necessary. Unless you convince me otherwise or read the spec
> > > > > differently than I do :) What do you think?
> > > > >
> > > >
> > > > "Reception and rejection"
> > > >
> > > > third-level filtering regarding "destination address" and if the
> > > > device is "PAN coordinator".
> > > > This is, in my opinion, what the coordinator boolean tells the
> > > > transceiver to do on hardware when doing address filter there. You can
> > > > also read that up in datasheets of transceivers as atf86rf233, search
> > > > for I_AM_COORD.
> > >
> > > Oh right, I now see what you mean!
> > >
> > > > Whereas they use the word "PAN coordinator" not "coordinator", if they
> > > > really make a difference there at this point..., if so then the kernel
> > > > must know if the coordinator is a pan coordinator or coordinator
> > > > because we need to set the address filter in kernel.
> > >
> > > Yes we need to make a difference, you can have several coordinators but
> > > a single PAN coordinator in a PAN. I think we can assume that the PAN
> > > coordinator is the coordinator with no parent (association-wise). With
> > > the addition of the association series, I can handle that, so I will
> > > create the two path as you advise, add a comment about this additional
> > > filter rule that we don't yet support, and finally after the
> > > association series add another commit to make this filtering rule real.
> > >
> > > >
> > > > > Thanks,
> > > > > Miquèl
> > > > >
> > > > > ---
> > > > >
> > > > > --- a/net/mac802154/rx.c
> > > > > +++ b/net/mac802154/rx.c
> > > > > @@ -194,6 +194,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > > >         int ret;
> > > > >         struct ieee802154_sub_if_data *sdata;
> > > > >         struct ieee802154_hdr hdr;
> > > > > +       bool iface_found = false;
> > > > >
> > > > >         ret = ieee802154_parse_frame_start(skb, &hdr);
> > > > >         if (ret) {
> > > > > @@ -203,18 +204,31 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > > >         }
> > > > >
> > > > >         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> > > > > -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> > > > > +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
> > > > >                         continue;
> > > > >
> > > > >                 if (!ieee802154_sdata_running(sdata))
> > > > >                         continue;
> > > > >
> > > > > +               iface_found = true;
> > > > > +               break;
> > > > > +       }
> > > > > +
> > > > > +       if (!iface_found) {
> > > > > +               kfree_skb(skb);
> > > > > +               return;
> > > > > +       }
> > > > > +
> > > > > +       /* TBD: Additional filtering is possible on NODEs and/or COORDINATORs */
> > > > > +       switch (sdata->wpan_dev.iftype) {
> > > > > +       case NL802154_IFTYPE_COORD:
> > > > > +       case NL802154_IFTYPE_NODE:
> > > > >                 ieee802154_subif_frame(sdata, skb, &hdr);
> > > > > -               skb = NULL;
> > > > > +               break;
> > > > > +       default:
> > > > > +               kfree_skb(skb);
> > > > >                 break;
> > > > >         }
> > > >
> > > > Why do you remove the whole interface looping above and make it only
> > > > run for one ?first found? ?
> > >
> > > To reduce the indentation level.
> > >
> > > > That code changes this behaviour and I do
> > > > not know why.
> > >
> > > The precedent code did:
> > > for_each_iface() {
> > >         if (not a node)
> > >                 continue;
> > >         if (not running)
> > >                 continue;
> > >
> > >         subif_frame();
> > >         break;
> > > }
> > >
> > > That final break also elected only the first running node iface.
> > > Otherwise it would mean that we allow the same skb to be consumed
> > > twice, which is wrong IMHO?
> >
> > no? Why is that wrong? There is a real use-case to have multiple
> > interfaces on one phy (or to do it in near future, I said that
> > multiple times). This patch does a step backwards to this.
>
> So we need to duplicate the skb because it automatically gets freed in
> the "forward to upper layer" path. Am I right? I'm fine doing so if

What is the definition of "duplicate the skb" here.

> this is the way to go, but I am interested if you can give me a real
> use case where having NODE+COORDINATOR on the same PHY is useful?
>

Testing.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-25 12:58                     ` Miquel Raynal
@ 2022-08-26  1:05                       ` Alexander Aring
  2022-08-26  7:54                         ` Miquel Raynal
  0 siblings, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-08-26  1:05 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Thu, Aug 25, 2022 at 8:58 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> Hi Alexander,
>
> aahringo@redhat.com wrote on Wed, 24 Aug 2022 17:53:45 -0400:
>
> > Hi,
> >
> > On Wed, Aug 24, 2022 at 9:27 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > >
> > > Hi Alexander,
> > >
> > > aahringo@redhat.com wrote on Wed, 24 Aug 2022 08:43:20 -0400:
> > >
> > > > Hi,
> > > >
> > > > On Wed, Aug 24, 2022 at 6:21 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > > ...
> > > > >
> > > > > Actually right now the second level is not enforced, and all the
> > > > > filtering levels are a bit fuzzy and spread everywhere in rx.c.
> > > > >
> > > > > I'm gonna see if I can at least clarify all of that and only make
> > > > > coord-dependent the right section because right now a
> > > > > ieee802154_coord_rx() path in ieee802154_rx_handle_packet() does not
> > > > > really make sense given that the level 3 filtering rules are mostly
> > > > > enforced in ieee802154_subif_frame().
> > > >
> > > > One thing I mentioned before is that we probably like to have a
> > > > parameter for rx path to give mac802154 a hint on which filtering
> > > > level it was received. We don't have that, I currently see that this
> > > > is a parameter for hwsim receiving it on promiscuous level only and
> > > > all others do third level filtering.
> > > > We need that now, because the promiscuous mode was only used for
> > > > sniffing which goes directly into the rx path for monitors. With scan
> > > > we mix things up here and in my opinion require such a parameter and
> > > > do filtering if necessary.
> > >
> > > I am currently trying to implement a slightly different approach. The
> > > core does not know hwsim is always in promiscuous mode, but it does
> > > know that it does not check FCS. So the core checks it. This is
> > > level 1 achieved. Then in level 2 we want to know if the core asked
> > > the transceiver to enter promiscuous mode, which, if it did, should
> > > not imply more filtering. If the device is working in promiscuous
> > > mode but this was not asked explicitly by the core, we don't really
> > > care, software filtering will apply anyway.
> > >
> >
> > I doubt that I will be happy with this solution, this all sounds like
> > "for the specific current behaviour that we support 2 filtering levels
> > it will work", just do a parameter on which 802.15.4 filtering level
> > it was received and the rx path will check what kind of filter is
> > required and which not.
> > As driver ops start() callback you should say which filtering level
> > the receive mode should start with.
> >
> > > I am reworking the rx path to clarify what is being done and when,
> > > because I found this part very obscure right now. In the end I don't
> > > think we need additional rx info from the drivers. Hopefully my
> > > proposal will clarify why this is (IMHO) not needed.
> > >
> >
> > Never looked much in 802.15.4 receive path as it just worked but I
> > said that there might be things to clean up when filtering things on
> > hardware and when on software and I have the feeling we are doing
> > things twice. Sometimes it is also necessary to set some skb fields
> > e.g. PACKET_HOST, etc. and I think this is what the most important
> > part of it is there. However, there are probably some tune ups if we
> > know we are in third leveling filtering...
>
> Ok, I've done the following.
>
> - Adding a PHY parameter which reflects the actual filtering level of
>   the transceiver, the default level is 4 (standard situation, you're

3?

>   receiving data) but of course if the PHY does not support this state
>   (like hwsim) it should overwrite this value by setting the actual
>   filtering level (none, in the hwsim case) so that the core knows what
>   it receives.
>

ok.

> - I've replaced the specific "do not check the FCS" flag only used by
>   hwsim by this filtering level, which gives all the information we
>   need.
>

ok.

> - I've added a real promiscuous filtering mode which truly does not
>   care about the content of the frame but only checks the FCS if not
>   already done by the xceiver.
>

not sure what a "real promiscuous filtering here is" people have
different understanding about it, but 802.15.4 has a definition for
it. You should consider that having monitors, frames with bad fcs
should not be filtered out by hardware. There it comes back what I
said before, the filtering level should be a parameter for start()
driver ops.

> - I've also implemented in software filtering level 4 for most regular

3?

>   data packets. Without changing the default PHY level mentioned in the
>   first item above, this additional filtering will be skipped which
>   ensures we keep the same behavior of most driver. In the case of hwsim
>   however, these filters will become active if the MAC is not in
>   promiscuous mode or in scan mode, which is actually what people
>   should be expecting.
>

To give feedback to that I need to see code. And please don't send the
whole feature stuff again, just this specific part of it. Thanks.

> Hopefully all this fits what you had in mind.
>
> I have one item left on my current todo list: improving a bit the
> userspace tool with a "monitor" command.
>
> Otherwise the remaining things to do are to discuss the locking design
> which might need to be changed to avoid lockdep issues and keep the
> rtnl locked eg. during a channel change. I still don't know how to do
> that, so it's likely that the right next version will not include any
> change in this area unless something pops up.

I try to look at that on the weekend.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-26  0:51                   ` Alexander Aring
@ 2022-08-26  1:35                     ` Alexander Aring
  2022-08-26  8:08                       ` Miquel Raynal
  2022-08-26  7:30                     ` Miquel Raynal
  1 sibling, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-08-26  1:35 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Thu, Aug 25, 2022 at 8:51 PM Alexander Aring <aahringo@redhat.com> wrote:
>
> Hi,
>
> On Thu, Aug 25, 2022 at 4:41 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> >
> > Hi Alexander,
> >
> > aahringo@redhat.com wrote on Wed, 24 Aug 2022 17:43:11 -0400:
> >
> > > On Wed, Aug 24, 2022 at 3:35 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > >
> > > > Hi Alexander,
> > > >
> > > > aahringo@redhat.com wrote on Tue, 23 Aug 2022 17:44:52 -0400:
> > > >
> > > > > Hi,
> > > > >
> > > > > On Tue, Aug 23, 2022 at 12:29 PM Miquel Raynal
> > > > > <miquel.raynal@bootlin.com> wrote:
> > > > > >
> > > > > > Hi Alexander,
> > > > > >
> > > > > > aahringo@redhat.com wrote on Tue, 23 Aug 2022 08:33:30 -0400:
> > > > > >
> > > > > > > Hi,
> > > > > > >
> > > > > > > On Fri, Aug 19, 2022 at 1:11 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > > > > > >
> > > > > > > > Hi Alexander,
> > > > > > > >
> > > > > > > > aahringo@redhat.com wrote on Tue, 5 Jul 2022 21:51:02 -0400:
> > > > > > > >
> > > > > > > > > Hi,
> > > > > > > > >
> > > > > > > > > On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > > > > > > > >
> > > > > > > > > > As a first strep in introducing proper PAN management and association,
> > > > > > > > > > we need to be able to create coordinator interfaces which might act as
> > > > > > > > > > coordinator or PAN coordinator.
> > > > > > > > > >
> > > > > > > > > > Hence, let's add the minimum support to allow the creation of these
> > > > > > > > > > interfaces. This might be restrained and improved later.
> > > > > > > > > >
> > > > > > > > > > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > > > > > > > > > ---
> > > > > > > > > >  net/mac802154/iface.c | 14 ++++++++------
> > > > > > > > > >  net/mac802154/rx.c    |  2 +-
> > > > > > > > > >  2 files changed, 9 insertions(+), 7 deletions(-)
> > > > > > > > > >
> > > > > > > > > > diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
> > > > > > > > > > index 500ed1b81250..7ac0c5685d3f 100644
> > > > > > > > > > --- a/net/mac802154/iface.c
> > > > > > > > > > +++ b/net/mac802154/iface.c
> > > > > > > > > > @@ -273,13 +273,13 @@ ieee802154_check_concurrent_iface(struct ieee802154_sub_if_data *sdata,
> > > > > > > > > >                 if (nsdata != sdata && ieee802154_sdata_running(nsdata)) {
> > > > > > > > > >                         int ret;
> > > > > > > > > >
> > > > > > > > > > -                       /* TODO currently we don't support multiple node types
> > > > > > > > > > -                        * we need to run skb_clone at rx path. Check if there
> > > > > > > > > > -                        * exist really an use case if we need to support
> > > > > > > > > > -                        * multiple node types at the same time.
> > > > > > > > > > +                       /* TODO currently we don't support multiple node/coord
> > > > > > > > > > +                        * types we need to run skb_clone at rx path. Check if
> > > > > > > > > > +                        * there exist really an use case if we need to support
> > > > > > > > > > +                        * multiple node/coord types at the same time.
> > > > > > > > > >                          */
> > > > > > > > > > -                       if (wpan_dev->iftype == NL802154_IFTYPE_NODE &&
> > > > > > > > > > -                           nsdata->wpan_dev.iftype == NL802154_IFTYPE_NODE)
> > > > > > > > > > +                       if (wpan_dev->iftype != NL802154_IFTYPE_MONITOR &&
> > > > > > > > > > +                           nsdata->wpan_dev.iftype != NL802154_IFTYPE_MONITOR)
> > > > > > > > > >                                 return -EBUSY;
> > > > > > > > > >
> > > > > > > > > >                         /* check all phy mac sublayer settings are the same.
> > > > > > > > > > @@ -577,6 +577,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
> > > > > > > > > >         wpan_dev->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
> > > > > > > > > >
> > > > > > > > > >         switch (type) {
> > > > > > > > > > +       case NL802154_IFTYPE_COORD:
> > > > > > > > > >         case NL802154_IFTYPE_NODE:
> > > > > > > > > >                 ieee802154_be64_to_le64(&wpan_dev->extended_addr,
> > > > > > > > > >                                         sdata->dev->dev_addr);
> > > > > > > > > > @@ -636,6 +637,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
> > > > > > > > > >         ieee802154_le64_to_be64(ndev->perm_addr,
> > > > > > > > > >                                 &local->hw.phy->perm_extended_addr);
> > > > > > > > > >         switch (type) {
> > > > > > > > > > +       case NL802154_IFTYPE_COORD:
> > > > > > > > > >         case NL802154_IFTYPE_NODE:
> > > > > > > > > >                 ndev->type = ARPHRD_IEEE802154;
> > > > > > > > > >                 if (ieee802154_is_valid_extended_unicast_addr(extended_addr)) {
> > > > > > > > > > diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
> > > > > > > > > > index b8ce84618a55..39459d8d787a 100644
> > > > > > > > > > --- a/net/mac802154/rx.c
> > > > > > > > > > +++ b/net/mac802154/rx.c
> > > > > > > > > > @@ -203,7 +203,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > > > > > > > >         }
> > > > > > > > > >
> > > > > > > > > >         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> > > > > > > > > > -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> > > > > > > > > > +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
> > > > > > > > > >                         continue;
> > > > > > > > >
> > > > > > > > > I probably get why you are doing that, but first the overall design is
> > > > > > > > > working differently - means you should add an additional receive path
> > > > > > > > > for the special interface type.
> > > > > > > > >
> > > > > > > > > Also we "discovered" before that the receive path of node vs
> > > > > > > > > coordinator is different... Where is the different handling here? I
> > > > > > > > > don't see it, I see that NODE and COORD are the same now (because that
> > > > > > > > > is _currently_ everything else than monitor). This change is not
> > > > > > > > > enough and does "something" to handle in some way coordinator receive
> > > > > > > > > path but there are things missing.
> > > > > > > > >
> > > > > > > > > 1. Changing the address filters that it signals the transceiver it's
> > > > > > > > > acting as coordinator
> > > > > > > > > 2. We _should_ also have additional handling for whatever the
> > > > > > > > > additional handling what address filters are doing in mac802154
> > > > > > > > > _because_ there is hardware which doesn't have address filtering e.g.
> > > > > > > > > hwsim which depend that this is working in software like other
> > > > > > > > > transceiver hardware address filters.
> > > > > > > > >
> > > > > > > > > For the 2. one, I don't know if we do that even for NODE right or we
> > > > > > > > > just have the bare minimal support there... I don't assume that
> > > > > > > > > everything is working correctly here but what I want to see is a
> > > > > > > > > separate receive path for coordinators that people can send patches to
> > > > > > > > > fix it.
> > > > > > > >
> > > > > > > > Yes, we do very little differently between the two modes, that's why I
> > > > > > > > took the easy way: just changing the condition. I really don't see what
> > > > > > > > I can currently add here, but I am fine changing the style to easily
> > > > > > > > show people where to add filters for such or such interface, but right
> > > > > > > > now both path will look very "identical", do we agree on that?
> > > > > > >
> > > > > > > mostly yes, but there exists a difference and we should at least check
> > > > > > > if the node receive path violates the coordinator receive path and
> > > > > > > vice versa.
> > > > > > > Put it in a receive_path() function and then coord_receive_path(),
> > > > > > > node_receive_path() that calls the receive_path() and do the
> > > > > > > additional filtering for coordinators, etc.
> > > > > > >
> > > > > > > There should be a part in the standard about "third level filter rule
> > > > > > > if it's a coordinator".
> > > > > > > btw: this is because the address filter on the transceiver needs to
> > > > > > > have the "i am a coordinator" boolean set which is missing in this
> > > > > > > series. However it depends on the transceiver filtering level and the
> > > > > > > mac802154 receive path if we actually need to run such filtering or
> > > > > > > not.
> > > > > >
> > > > > > I must be missing some information because I can't find any places
> > > > > > where what you suggest is described in the spec.
> > > > > >
> > > > > > I agree there are multiple filtering level so let's go through them one
> > > > > > by one (6.7.2 Reception and rejection):
> > > > > > - first level: is the checksum (FCS) valid?
> > > > > >         yes -> goto second level
> > > > > >         no -> drop
> > > > > > - second level: are we in promiscuous mode?
> > > > > >         yes -> forward to upper layers
> > > > > >         no -> goto second level (bis)
> > > > > > - second level (bis): are we scanning?
> > > > > >         yes -> goto scan filtering
> > > > > >         no -> goto third level
> > > > > > - scan filtering: is it a beacon?
> > > > > >         yes -> process the beacon
> > > > > >         no -> drop
> > > > > > - third level: is the frame valid? (type, source, destination, pan id,
> > > > > >   etc)
> > > > > >         yes -> forward to upper layers
> > > > > >         no -> drop
> > > > > >
> > > > > > But none of them, as you said, is dependent on the interface type.
> > > > > > There is no mention of a specific filtering operation to do in all
> > > > > > those cases when running in COORD mode. So I still don't get what
> > > > > > should be included in either node_receive_path() which should be
> > > > > > different than in coord_receive_path() for now.
> > > > > >
> > > > > > There are, however, two situations where the interface type has its
> > > > > > importance:
> > > > > > - Enhanced beacon requests with Enhanced beacon filter IE, which asks
> > > > > >   the receiving device to process/drop the request upon certain
> > > > > >   conditions (minimum LQI and/or randomness), as detailed in
> > > > > >   7.4.4.6 Enhanced Beacon Filter IE. But, as mentioned in
> > > > > >   7.5.9 Enhanced Beacon Request command: "The Enhanced Beacon Request
> > > > > >   command is optional for an FFD and an RFD", so this series was only
> > > > > >   targeting basic beaconing for now.
> > > > > > - In relaying mode, the destination address must not be validated
> > > > > >   because the message needs to be re-emitted. Indeed, a receiver in
> > > > > >   relaying mode may not be the recipient. This is also optional and out
> > > > > >   of the scope of this series.
> > > > > >
> > > > > > Right now I have the below diff, which clarifies the two path, without
> > > > > > too much changes in the current code because I don't really see why it
> > > > > > would be necessary. Unless you convince me otherwise or read the spec
> > > > > > differently than I do :) What do you think?
> > > > > >
> > > > >
> > > > > "Reception and rejection"
> > > > >
> > > > > third-level filtering regarding "destination address" and if the
> > > > > device is "PAN coordinator".
> > > > > This is, in my opinion, what the coordinator boolean tells the
> > > > > transceiver to do on hardware when doing address filter there. You can
> > > > > also read that up in datasheets of transceivers as atf86rf233, search
> > > > > for I_AM_COORD.
> > > >
> > > > Oh right, I now see what you mean!
> > > >
> > > > > Whereas they use the word "PAN coordinator" not "coordinator", if they
> > > > > really make a difference there at this point..., if so then the kernel
> > > > > must know if the coordinator is a pan coordinator or coordinator
> > > > > because we need to set the address filter in kernel.
> > > >
> > > > Yes we need to make a difference, you can have several coordinators but
> > > > a single PAN coordinator in a PAN. I think we can assume that the PAN
> > > > coordinator is the coordinator with no parent (association-wise). With
> > > > the addition of the association series, I can handle that, so I will
> > > > create the two path as you advise, add a comment about this additional
> > > > filter rule that we don't yet support, and finally after the
> > > > association series add another commit to make this filtering rule real.
> > > >
> > > > >
> > > > > > Thanks,
> > > > > > Miquèl
> > > > > >
> > > > > > ---
> > > > > >
> > > > > > --- a/net/mac802154/rx.c
> > > > > > +++ b/net/mac802154/rx.c
> > > > > > @@ -194,6 +194,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > > > >         int ret;
> > > > > >         struct ieee802154_sub_if_data *sdata;
> > > > > >         struct ieee802154_hdr hdr;
> > > > > > +       bool iface_found = false;
> > > > > >
> > > > > >         ret = ieee802154_parse_frame_start(skb, &hdr);
> > > > > >         if (ret) {
> > > > > > @@ -203,18 +204,31 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > > > >         }
> > > > > >
> > > > > >         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> > > > > > -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> > > > > > +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
> > > > > >                         continue;
> > > > > >
> > > > > >                 if (!ieee802154_sdata_running(sdata))
> > > > > >                         continue;
> > > > > >
> > > > > > +               iface_found = true;
> > > > > > +               break;
> > > > > > +       }
> > > > > > +
> > > > > > +       if (!iface_found) {
> > > > > > +               kfree_skb(skb);
> > > > > > +               return;
> > > > > > +       }
> > > > > > +
> > > > > > +       /* TBD: Additional filtering is possible on NODEs and/or COORDINATORs */
> > > > > > +       switch (sdata->wpan_dev.iftype) {
> > > > > > +       case NL802154_IFTYPE_COORD:
> > > > > > +       case NL802154_IFTYPE_NODE:
> > > > > >                 ieee802154_subif_frame(sdata, skb, &hdr);
> > > > > > -               skb = NULL;
> > > > > > +               break;
> > > > > > +       default:
> > > > > > +               kfree_skb(skb);
> > > > > >                 break;
> > > > > >         }
> > > > >
> > > > > Why do you remove the whole interface looping above and make it only
> > > > > run for one ?first found? ?
> > > >
> > > > To reduce the indentation level.
> > > >
> > > > > That code changes this behaviour and I do
> > > > > not know why.
> > > >
> > > > The precedent code did:
> > > > for_each_iface() {
> > > >         if (not a node)
> > > >                 continue;
> > > >         if (not running)
> > > >                 continue;
> > > >
> > > >         subif_frame();
> > > >         break;
> > > > }
> > > >
> > > > That final break also elected only the first running node iface.
> > > > Otherwise it would mean that we allow the same skb to be consumed
> > > > twice, which is wrong IMHO?
> > >
> > > no? Why is that wrong? There is a real use-case to have multiple
> > > interfaces on one phy (or to do it in near future, I said that
> > > multiple times). This patch does a step backwards to this.
> >
> > So we need to duplicate the skb because it automatically gets freed in
> > the "forward to upper layer" path. Am I right? I'm fine doing so if
>
> What is the definition of "duplicate the skb" here.
>
> > this is the way to go, but I am interested if you can give me a real
> > use case where having NODE+COORDINATOR on the same PHY is useful?
> >
>
> Testing.

I need to say that I really used multiple monitors at the same time on
one phy only and I did that with hwsim to run multiple user space
stacks. It was working and I was happy and didn't need to do a lot of
phy creations in hwsim. Most hardware can probably not run multiple
nodes and coordinators at the same time ?yet?, _but_ there is a
candidate which can do that and this is atusb. On atusb we have a
co-processor that can deal with multiple address filters. People
already asked to do something like a node which can operate on two
pans as I remember, that would be a candidate for such a feature. I
really don't want to move step backwards here and delete this thing
which probably can be useful later. I don't know how wireless history
dealt with it and how complicated it was to bring such a feature in to
e.g. run multiple access points on one phy. I also see it in ethernet
with macvlan, which is a similar feature.

We don't need to support it, make it so that on an ifup it returns
-EBUSY if something doesn't fit together as it currently is. We can
later add support for it after playing around with hwsim a little bit
more. We should at least take care that I can still run my multiple
monitors at the same time (which is currently allowed).

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-26  0:51                   ` Alexander Aring
  2022-08-26  1:35                     ` Alexander Aring
@ 2022-08-26  7:30                     ` Miquel Raynal
  1 sibling, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-08-26  7:30 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Thu, 25 Aug 2022 20:51:49 -0400:

> Hi,
> 
> On Thu, Aug 25, 2022 at 4:41 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> >
> > Hi Alexander,
> >
> > aahringo@redhat.com wrote on Wed, 24 Aug 2022 17:43:11 -0400:
> >  
> > > On Wed, Aug 24, 2022 at 3:35 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > > >
> > > > Hi Alexander,
> > > >
> > > > aahringo@redhat.com wrote on Tue, 23 Aug 2022 17:44:52 -0400:
> > > >  
> > > > > Hi,
> > > > >
> > > > > On Tue, Aug 23, 2022 at 12:29 PM Miquel Raynal
> > > > > <miquel.raynal@bootlin.com> wrote:  
> > > > > >
> > > > > > Hi Alexander,
> > > > > >
> > > > > > aahringo@redhat.com wrote on Tue, 23 Aug 2022 08:33:30 -0400:
> > > > > >  
> > > > > > > Hi,
> > > > > > >
> > > > > > > On Fri, Aug 19, 2022 at 1:11 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > > > > > > >
> > > > > > > > Hi Alexander,
> > > > > > > >
> > > > > > > > aahringo@redhat.com wrote on Tue, 5 Jul 2022 21:51:02 -0400:
> > > > > > > >  
> > > > > > > > > Hi,
> > > > > > > > >
> > > > > > > > > On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > > > > > > > > >
> > > > > > > > > > As a first strep in introducing proper PAN management and association,
> > > > > > > > > > we need to be able to create coordinator interfaces which might act as
> > > > > > > > > > coordinator or PAN coordinator.
> > > > > > > > > >
> > > > > > > > > > Hence, let's add the minimum support to allow the creation of these
> > > > > > > > > > interfaces. This might be restrained and improved later.
> > > > > > > > > >
> > > > > > > > > > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > > > > > > > > > ---
> > > > > > > > > >  net/mac802154/iface.c | 14 ++++++++------
> > > > > > > > > >  net/mac802154/rx.c    |  2 +-
> > > > > > > > > >  2 files changed, 9 insertions(+), 7 deletions(-)
> > > > > > > > > >
> > > > > > > > > > diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
> > > > > > > > > > index 500ed1b81250..7ac0c5685d3f 100644
> > > > > > > > > > --- a/net/mac802154/iface.c
> > > > > > > > > > +++ b/net/mac802154/iface.c
> > > > > > > > > > @@ -273,13 +273,13 @@ ieee802154_check_concurrent_iface(struct ieee802154_sub_if_data *sdata,
> > > > > > > > > >                 if (nsdata != sdata && ieee802154_sdata_running(nsdata)) {
> > > > > > > > > >                         int ret;
> > > > > > > > > >
> > > > > > > > > > -                       /* TODO currently we don't support multiple node types
> > > > > > > > > > -                        * we need to run skb_clone at rx path. Check if there
> > > > > > > > > > -                        * exist really an use case if we need to support
> > > > > > > > > > -                        * multiple node types at the same time.
> > > > > > > > > > +                       /* TODO currently we don't support multiple node/coord
> > > > > > > > > > +                        * types we need to run skb_clone at rx path. Check if
> > > > > > > > > > +                        * there exist really an use case if we need to support
> > > > > > > > > > +                        * multiple node/coord types at the same time.
> > > > > > > > > >                          */
> > > > > > > > > > -                       if (wpan_dev->iftype == NL802154_IFTYPE_NODE &&
> > > > > > > > > > -                           nsdata->wpan_dev.iftype == NL802154_IFTYPE_NODE)
> > > > > > > > > > +                       if (wpan_dev->iftype != NL802154_IFTYPE_MONITOR &&
> > > > > > > > > > +                           nsdata->wpan_dev.iftype != NL802154_IFTYPE_MONITOR)
> > > > > > > > > >                                 return -EBUSY;
> > > > > > > > > >
> > > > > > > > > >                         /* check all phy mac sublayer settings are the same.
> > > > > > > > > > @@ -577,6 +577,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
> > > > > > > > > >         wpan_dev->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
> > > > > > > > > >
> > > > > > > > > >         switch (type) {
> > > > > > > > > > +       case NL802154_IFTYPE_COORD:
> > > > > > > > > >         case NL802154_IFTYPE_NODE:
> > > > > > > > > >                 ieee802154_be64_to_le64(&wpan_dev->extended_addr,
> > > > > > > > > >                                         sdata->dev->dev_addr);
> > > > > > > > > > @@ -636,6 +637,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
> > > > > > > > > >         ieee802154_le64_to_be64(ndev->perm_addr,
> > > > > > > > > >                                 &local->hw.phy->perm_extended_addr);
> > > > > > > > > >         switch (type) {
> > > > > > > > > > +       case NL802154_IFTYPE_COORD:
> > > > > > > > > >         case NL802154_IFTYPE_NODE:
> > > > > > > > > >                 ndev->type = ARPHRD_IEEE802154;
> > > > > > > > > >                 if (ieee802154_is_valid_extended_unicast_addr(extended_addr)) {
> > > > > > > > > > diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
> > > > > > > > > > index b8ce84618a55..39459d8d787a 100644
> > > > > > > > > > --- a/net/mac802154/rx.c
> > > > > > > > > > +++ b/net/mac802154/rx.c
> > > > > > > > > > @@ -203,7 +203,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > > > > > > > >         }
> > > > > > > > > >
> > > > > > > > > >         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> > > > > > > > > > -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> > > > > > > > > > +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
> > > > > > > > > >                         continue;  
> > > > > > > > >
> > > > > > > > > I probably get why you are doing that, but first the overall design is
> > > > > > > > > working differently - means you should add an additional receive path
> > > > > > > > > for the special interface type.
> > > > > > > > >
> > > > > > > > > Also we "discovered" before that the receive path of node vs
> > > > > > > > > coordinator is different... Where is the different handling here? I
> > > > > > > > > don't see it, I see that NODE and COORD are the same now (because that
> > > > > > > > > is _currently_ everything else than monitor). This change is not
> > > > > > > > > enough and does "something" to handle in some way coordinator receive
> > > > > > > > > path but there are things missing.
> > > > > > > > >
> > > > > > > > > 1. Changing the address filters that it signals the transceiver it's
> > > > > > > > > acting as coordinator
> > > > > > > > > 2. We _should_ also have additional handling for whatever the
> > > > > > > > > additional handling what address filters are doing in mac802154
> > > > > > > > > _because_ there is hardware which doesn't have address filtering e.g.
> > > > > > > > > hwsim which depend that this is working in software like other
> > > > > > > > > transceiver hardware address filters.
> > > > > > > > >
> > > > > > > > > For the 2. one, I don't know if we do that even for NODE right or we
> > > > > > > > > just have the bare minimal support there... I don't assume that
> > > > > > > > > everything is working correctly here but what I want to see is a
> > > > > > > > > separate receive path for coordinators that people can send patches to
> > > > > > > > > fix it.  
> > > > > > > >
> > > > > > > > Yes, we do very little differently between the two modes, that's why I
> > > > > > > > took the easy way: just changing the condition. I really don't see what
> > > > > > > > I can currently add here, but I am fine changing the style to easily
> > > > > > > > show people where to add filters for such or such interface, but right
> > > > > > > > now both path will look very "identical", do we agree on that?  
> > > > > > >
> > > > > > > mostly yes, but there exists a difference and we should at least check
> > > > > > > if the node receive path violates the coordinator receive path and
> > > > > > > vice versa.
> > > > > > > Put it in a receive_path() function and then coord_receive_path(),
> > > > > > > node_receive_path() that calls the receive_path() and do the
> > > > > > > additional filtering for coordinators, etc.
> > > > > > >
> > > > > > > There should be a part in the standard about "third level filter rule
> > > > > > > if it's a coordinator".
> > > > > > > btw: this is because the address filter on the transceiver needs to
> > > > > > > have the "i am a coordinator" boolean set which is missing in this
> > > > > > > series. However it depends on the transceiver filtering level and the
> > > > > > > mac802154 receive path if we actually need to run such filtering or
> > > > > > > not.  
> > > > > >
> > > > > > I must be missing some information because I can't find any places
> > > > > > where what you suggest is described in the spec.
> > > > > >
> > > > > > I agree there are multiple filtering level so let's go through them one
> > > > > > by one (6.7.2 Reception and rejection):
> > > > > > - first level: is the checksum (FCS) valid?
> > > > > >         yes -> goto second level
> > > > > >         no -> drop
> > > > > > - second level: are we in promiscuous mode?
> > > > > >         yes -> forward to upper layers
> > > > > >         no -> goto second level (bis)
> > > > > > - second level (bis): are we scanning?
> > > > > >         yes -> goto scan filtering
> > > > > >         no -> goto third level
> > > > > > - scan filtering: is it a beacon?
> > > > > >         yes -> process the beacon
> > > > > >         no -> drop
> > > > > > - third level: is the frame valid? (type, source, destination, pan id,
> > > > > >   etc)
> > > > > >         yes -> forward to upper layers
> > > > > >         no -> drop
> > > > > >
> > > > > > But none of them, as you said, is dependent on the interface type.
> > > > > > There is no mention of a specific filtering operation to do in all
> > > > > > those cases when running in COORD mode. So I still don't get what
> > > > > > should be included in either node_receive_path() which should be
> > > > > > different than in coord_receive_path() for now.
> > > > > >
> > > > > > There are, however, two situations where the interface type has its
> > > > > > importance:
> > > > > > - Enhanced beacon requests with Enhanced beacon filter IE, which asks
> > > > > >   the receiving device to process/drop the request upon certain
> > > > > >   conditions (minimum LQI and/or randomness), as detailed in
> > > > > >   7.4.4.6 Enhanced Beacon Filter IE. But, as mentioned in
> > > > > >   7.5.9 Enhanced Beacon Request command: "The Enhanced Beacon Request
> > > > > >   command is optional for an FFD and an RFD", so this series was only
> > > > > >   targeting basic beaconing for now.
> > > > > > - In relaying mode, the destination address must not be validated
> > > > > >   because the message needs to be re-emitted. Indeed, a receiver in
> > > > > >   relaying mode may not be the recipient. This is also optional and out
> > > > > >   of the scope of this series.
> > > > > >
> > > > > > Right now I have the below diff, which clarifies the two path, without
> > > > > > too much changes in the current code because I don't really see why it
> > > > > > would be necessary. Unless you convince me otherwise or read the spec
> > > > > > differently than I do :) What do you think?
> > > > > >  
> > > > >
> > > > > "Reception and rejection"
> > > > >
> > > > > third-level filtering regarding "destination address" and if the
> > > > > device is "PAN coordinator".
> > > > > This is, in my opinion, what the coordinator boolean tells the
> > > > > transceiver to do on hardware when doing address filter there. You can
> > > > > also read that up in datasheets of transceivers as atf86rf233, search
> > > > > for I_AM_COORD.  
> > > >
> > > > Oh right, I now see what you mean!
> > > >  
> > > > > Whereas they use the word "PAN coordinator" not "coordinator", if they
> > > > > really make a difference there at this point..., if so then the kernel
> > > > > must know if the coordinator is a pan coordinator or coordinator
> > > > > because we need to set the address filter in kernel.  
> > > >
> > > > Yes we need to make a difference, you can have several coordinators but
> > > > a single PAN coordinator in a PAN. I think we can assume that the PAN
> > > > coordinator is the coordinator with no parent (association-wise). With
> > > > the addition of the association series, I can handle that, so I will
> > > > create the two path as you advise, add a comment about this additional
> > > > filter rule that we don't yet support, and finally after the
> > > > association series add another commit to make this filtering rule real.
> > > >  
> > > > >  
> > > > > > Thanks,
> > > > > > Miquèl
> > > > > >
> > > > > > ---
> > > > > >
> > > > > > --- a/net/mac802154/rx.c
> > > > > > +++ b/net/mac802154/rx.c
> > > > > > @@ -194,6 +194,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > > > >         int ret;
> > > > > >         struct ieee802154_sub_if_data *sdata;
> > > > > >         struct ieee802154_hdr hdr;
> > > > > > +       bool iface_found = false;
> > > > > >
> > > > > >         ret = ieee802154_parse_frame_start(skb, &hdr);
> > > > > >         if (ret) {
> > > > > > @@ -203,18 +204,31 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > > > >         }
> > > > > >
> > > > > >         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> > > > > > -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> > > > > > +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
> > > > > >                         continue;
> > > > > >
> > > > > >                 if (!ieee802154_sdata_running(sdata))
> > > > > >                         continue;
> > > > > >
> > > > > > +               iface_found = true;
> > > > > > +               break;
> > > > > > +       }
> > > > > > +
> > > > > > +       if (!iface_found) {
> > > > > > +               kfree_skb(skb);
> > > > > > +               return;
> > > > > > +       }
> > > > > > +
> > > > > > +       /* TBD: Additional filtering is possible on NODEs and/or COORDINATORs */
> > > > > > +       switch (sdata->wpan_dev.iftype) {
> > > > > > +       case NL802154_IFTYPE_COORD:
> > > > > > +       case NL802154_IFTYPE_NODE:
> > > > > >                 ieee802154_subif_frame(sdata, skb, &hdr);
> > > > > > -               skb = NULL;
> > > > > > +               break;
> > > > > > +       default:
> > > > > > +               kfree_skb(skb);
> > > > > >                 break;
> > > > > >         }  
> > > > >
> > > > > Why do you remove the whole interface looping above and make it only
> > > > > run for one ?first found? ?  
> > > >
> > > > To reduce the indentation level.
> > > >  
> > > > > That code changes this behaviour and I do
> > > > > not know why.  
> > > >
> > > > The precedent code did:
> > > > for_each_iface() {
> > > >         if (not a node)
> > > >                 continue;
> > > >         if (not running)
> > > >                 continue;
> > > >
> > > >         subif_frame();
> > > >         break;
> > > > }
> > > >
> > > > That final break also elected only the first running node iface.
> > > > Otherwise it would mean that we allow the same skb to be consumed
> > > > twice, which is wrong IMHO?  
> > >
> > > no? Why is that wrong? There is a real use-case to have multiple
> > > interfaces on one phy (or to do it in near future, I said that
> > > multiple times). This patch does a step backwards to this.  
> >
> > So we need to duplicate the skb because it automatically gets freed in
> > the "forward to upper layer" path. Am I right? I'm fine doing so if  
> 
> What is the definition of "duplicate the skb" here.

skb2 = skb_clone(skb, GFP_ATOMIC);
if (skb2) {
	skb2->dev = sdata->dev;
	ieee802154_deliver_skb(skb2);
	...
}

This is exactly what the ieee80254_monitors_rx() function does, it
loops over all the monitor interfaces and each time there is one
running, copies the skb and consumes it by forwarding it to the upper
layers. I've done the same in the other path to keep the ability to use
more than one "visible" interface on the same PHY (by visible I mean:
not a monitor).

> > this is the way to go, but I am interested if you can give me a real
> > use case where having NODE+COORDINATOR on the same PHY is useful?
> >  
> 
> Testing.

Ok :-)


Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-26  1:05                       ` Alexander Aring
@ 2022-08-26  7:54                         ` Miquel Raynal
  2022-08-29  2:52                           ` Alexander Aring
  0 siblings, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-08-26  7:54 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Thu, 25 Aug 2022 21:05:09 -0400:

> Hi,
> 
> On Thu, Aug 25, 2022 at 8:58 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> >
> > Hi Alexander,
> >
> > aahringo@redhat.com wrote on Wed, 24 Aug 2022 17:53:45 -0400:
> >  
> > > Hi,
> > >
> > > On Wed, Aug 24, 2022 at 9:27 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > > >
> > > > Hi Alexander,
> > > >
> > > > aahringo@redhat.com wrote on Wed, 24 Aug 2022 08:43:20 -0400:
> > > >  
> > > > > Hi,
> > > > >
> > > > > On Wed, Aug 24, 2022 at 6:21 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > > > ...  
> > > > > >
> > > > > > Actually right now the second level is not enforced, and all the
> > > > > > filtering levels are a bit fuzzy and spread everywhere in rx.c.
> > > > > >
> > > > > > I'm gonna see if I can at least clarify all of that and only make
> > > > > > coord-dependent the right section because right now a
> > > > > > ieee802154_coord_rx() path in ieee802154_rx_handle_packet() does not
> > > > > > really make sense given that the level 3 filtering rules are mostly
> > > > > > enforced in ieee802154_subif_frame().  
> > > > >
> > > > > One thing I mentioned before is that we probably like to have a
> > > > > parameter for rx path to give mac802154 a hint on which filtering
> > > > > level it was received. We don't have that, I currently see that this
> > > > > is a parameter for hwsim receiving it on promiscuous level only and
> > > > > all others do third level filtering.
> > > > > We need that now, because the promiscuous mode was only used for
> > > > > sniffing which goes directly into the rx path for monitors. With scan
> > > > > we mix things up here and in my opinion require such a parameter and
> > > > > do filtering if necessary.  
> > > >
> > > > I am currently trying to implement a slightly different approach. The
> > > > core does not know hwsim is always in promiscuous mode, but it does
> > > > know that it does not check FCS. So the core checks it. This is
> > > > level 1 achieved. Then in level 2 we want to know if the core asked
> > > > the transceiver to enter promiscuous mode, which, if it did, should
> > > > not imply more filtering. If the device is working in promiscuous
> > > > mode but this was not asked explicitly by the core, we don't really
> > > > care, software filtering will apply anyway.
> > > >  
> > >
> > > I doubt that I will be happy with this solution, this all sounds like
> > > "for the specific current behaviour that we support 2 filtering levels
> > > it will work", just do a parameter on which 802.15.4 filtering level
> > > it was received and the rx path will check what kind of filter is
> > > required and which not.
> > > As driver ops start() callback you should say which filtering level
> > > the receive mode should start with.
> > >  
> > > > I am reworking the rx path to clarify what is being done and when,
> > > > because I found this part very obscure right now. In the end I don't
> > > > think we need additional rx info from the drivers. Hopefully my
> > > > proposal will clarify why this is (IMHO) not needed.
> > > >  
> > >
> > > Never looked much in 802.15.4 receive path as it just worked but I
> > > said that there might be things to clean up when filtering things on
> > > hardware and when on software and I have the feeling we are doing
> > > things twice. Sometimes it is also necessary to set some skb fields
> > > e.g. PACKET_HOST, etc. and I think this is what the most important
> > > part of it is there. However, there are probably some tune ups if we
> > > know we are in third leveling filtering...  
> >
> > Ok, I've done the following.
> >
> > - Adding a PHY parameter which reflects the actual filtering level of
> >   the transceiver, the default level is 4 (standard situation, you're  
> 
> 3?

Honestly there are only two filtering levels in the normal path and one
additional for scanning situations. But the spec mentions 4, so I
figured we should use the same naming to avoid confusing people on what
"level 3 means, if it's level 3 because level 1 and 2 are identical at
PHY level, or level 3 which is the scan filtering as mentioned in the
spec?".

I used this enum to clarify the amount of filtering that is involved,
hopefully it is clear enough. I remember we talked about this already
but an unrelated thread, and was not capable of finding it anymore O:-).

/** enum ieee802154_filtering_level - Filtering levels applicable to a PHY
 * @IEEE802154_FILTERING_NONE: No filtering at all, what is received is
 *	forwarded to the softMAC
 * @IEEE802154_FILTERING_1_FCS: First filtering level, frames with an invalid
 *	FCS should be dropped
 * @IEEE802154_FILTERING_2_PROMISCUOUS: Second filtering level, promiscuous
 *	mode, identical in terms of filtering to the first level at the PHY
 *	level, but no ACK should be transmitted automatically and at the MAC
 *	level the frame should be forwarded to the upper layer directly
 * @IEEE802154_FILTERING_3_SCAN: Third filtering level, enforced during scans,
 * 	which only forwards beacons
 * @IEEE802154_FILTERING_4_FRAME_FIELDS: Fourth filtering level actually
 *	enforcing the validity of the content of the frame with various checks
 */
enum ieee802154_filtering_level {
	IEEE802154_FILTERING_NONE,
	IEEE802154_FILTERING_1_FCS,
	IEEE802154_FILTERING_2_PROMISCUOUS,
	IEEE802154_FILTERING_3_SCAN,
	IEEE802154_FILTERING_4_FRAME_FIELDS,
};

> 
> >   receiving data) but of course if the PHY does not support this state
> >   (like hwsim) it should overwrite this value by setting the actual
> >   filtering level (none, in the hwsim case) so that the core knows what
> >   it receives.
> >  
> 
> ok.
> 
> > - I've replaced the specific "do not check the FCS" flag only used by
> >   hwsim by this filtering level, which gives all the information we
> >   need.
> >  
> 
> ok.
> 
> > - I've added a real promiscuous filtering mode which truly does not
> >   care about the content of the frame but only checks the FCS if not
> >   already done by the xceiver.
> >  
> 
> not sure what a "real promiscuous filtering here is" people have
> different understanding about it, but 802.15.4 has a definition for
> it.

Promiscuous, by the 802154 spec means: the FCS is good so the content of
the received packet must means something, just forward it and let upper
layers handle it.

Until now there was no real promiscuous mode in the mac NODE rx path.
Only monitors would get all the frames (including the ones with a wrong
FCS), which is fine because it's a bit out of the spec, so I'm fine
with this idea. But otherwise in the NODE/COORD rx path, the FCS should
be checked even in promiscuous mode to correctly match the spec.

Until now, ieee802154_parse_frame_start() was always called in these
path and this would validate the frame headers. I've added a more
precise promiscuous mode in the rx patch which skips any additional
checks. What happens however is that, if the transceiver disables FCS
checks in promiscuous mode, then FCS is not checked at all and this is
invalid. With my current implementation, the devices which do not check
the FCS might be easily "fixed" by changing their PHY filtering level
to "FILTERING_NONE" in the promiscuous callback.

> You should consider that having monitors, frames with bad fcs
> should not be filtered out by hardware. There it comes back what I
> said before, the filtering level should be a parameter for start()
> driver ops.
> 
> > - I've also implemented in software filtering level 4 for most
> > regular  
> 
> 3?
> 
> >   data packets. Without changing the default PHY level mentioned in
> > the first item above, this additional filtering will be skipped
> > which ensures we keep the same behavior of most driver. In the case
> > of hwsim however, these filters will become active if the MAC is
> > not in promiscuous mode or in scan mode, which is actually what
> > people should be expecting.
> >  
> 
> To give feedback to that I need to see code. And please don't send the
> whole feature stuff again, just this specific part of it. Thanks.

The entire filtering feature is split: there are the basis introduced
before the scan, and then after the whole scan+association thing I've
introduced additional filtering levels.

> > Hopefully all this fits what you had in mind.
> >
> > I have one item left on my current todo list: improving a bit the
> > userspace tool with a "monitor" command.
> >
> > Otherwise the remaining things to do are to discuss the locking
> > design which might need to be changed to avoid lockdep issues and
> > keep the rtnl locked eg. during a channel change. I still don't
> > know how to do that, so it's likely that the right next version
> > will not include any change in this area unless something pops up.  
> 
> I try to look at that on the weekend.

I've had an idea yesterday night which seem to work, I think I can drop
the two patches which you disliked regarding discarding the rtnl in the
tx path and in hwsim:change_channel().

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-26  1:35                     ` Alexander Aring
@ 2022-08-26  8:08                       ` Miquel Raynal
  2022-08-29  2:31                         ` Alexander Aring
  0 siblings, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-08-26  8:08 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Thu, 25 Aug 2022 21:35:05 -0400:

> Hi,
> 
> On Thu, Aug 25, 2022 at 8:51 PM Alexander Aring <aahringo@redhat.com> wrote:
> >
> > Hi,
> >
> > On Thu, Aug 25, 2022 at 4:41 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > >
> > > Hi Alexander,
> > >
> > > aahringo@redhat.com wrote on Wed, 24 Aug 2022 17:43:11 -0400:
> > >  
> > > > On Wed, Aug 24, 2022 at 3:35 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > > > >
> > > > > Hi Alexander,
> > > > >
> > > > > aahringo@redhat.com wrote on Tue, 23 Aug 2022 17:44:52 -0400:
> > > > >  
> > > > > > Hi,
> > > > > >
> > > > > > On Tue, Aug 23, 2022 at 12:29 PM Miquel Raynal
> > > > > > <miquel.raynal@bootlin.com> wrote:  
> > > > > > >
> > > > > > > Hi Alexander,
> > > > > > >
> > > > > > > aahringo@redhat.com wrote on Tue, 23 Aug 2022 08:33:30 -0400:
> > > > > > >  
> > > > > > > > Hi,
> > > > > > > >
> > > > > > > > On Fri, Aug 19, 2022 at 1:11 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > > > > > > > >
> > > > > > > > > Hi Alexander,
> > > > > > > > >
> > > > > > > > > aahringo@redhat.com wrote on Tue, 5 Jul 2022 21:51:02 -0400:
> > > > > > > > >  
> > > > > > > > > > Hi,
> > > > > > > > > >
> > > > > > > > > > On Fri, Jul 1, 2022 at 10:36 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > > > > > > > > > >
> > > > > > > > > > > As a first strep in introducing proper PAN management and association,
> > > > > > > > > > > we need to be able to create coordinator interfaces which might act as
> > > > > > > > > > > coordinator or PAN coordinator.
> > > > > > > > > > >
> > > > > > > > > > > Hence, let's add the minimum support to allow the creation of these
> > > > > > > > > > > interfaces. This might be restrained and improved later.
> > > > > > > > > > >
> > > > > > > > > > > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > > > > > > > > > > ---
> > > > > > > > > > >  net/mac802154/iface.c | 14 ++++++++------
> > > > > > > > > > >  net/mac802154/rx.c    |  2 +-
> > > > > > > > > > >  2 files changed, 9 insertions(+), 7 deletions(-)
> > > > > > > > > > >
> > > > > > > > > > > diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
> > > > > > > > > > > index 500ed1b81250..7ac0c5685d3f 100644
> > > > > > > > > > > --- a/net/mac802154/iface.c
> > > > > > > > > > > +++ b/net/mac802154/iface.c
> > > > > > > > > > > @@ -273,13 +273,13 @@ ieee802154_check_concurrent_iface(struct ieee802154_sub_if_data *sdata,
> > > > > > > > > > >                 if (nsdata != sdata && ieee802154_sdata_running(nsdata)) {
> > > > > > > > > > >                         int ret;
> > > > > > > > > > >
> > > > > > > > > > > -                       /* TODO currently we don't support multiple node types
> > > > > > > > > > > -                        * we need to run skb_clone at rx path. Check if there
> > > > > > > > > > > -                        * exist really an use case if we need to support
> > > > > > > > > > > -                        * multiple node types at the same time.
> > > > > > > > > > > +                       /* TODO currently we don't support multiple node/coord
> > > > > > > > > > > +                        * types we need to run skb_clone at rx path. Check if
> > > > > > > > > > > +                        * there exist really an use case if we need to support
> > > > > > > > > > > +                        * multiple node/coord types at the same time.
> > > > > > > > > > >                          */
> > > > > > > > > > > -                       if (wpan_dev->iftype == NL802154_IFTYPE_NODE &&
> > > > > > > > > > > -                           nsdata->wpan_dev.iftype == NL802154_IFTYPE_NODE)
> > > > > > > > > > > +                       if (wpan_dev->iftype != NL802154_IFTYPE_MONITOR &&
> > > > > > > > > > > +                           nsdata->wpan_dev.iftype != NL802154_IFTYPE_MONITOR)
> > > > > > > > > > >                                 return -EBUSY;
> > > > > > > > > > >
> > > > > > > > > > >                         /* check all phy mac sublayer settings are the same.
> > > > > > > > > > > @@ -577,6 +577,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
> > > > > > > > > > >         wpan_dev->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
> > > > > > > > > > >
> > > > > > > > > > >         switch (type) {
> > > > > > > > > > > +       case NL802154_IFTYPE_COORD:
> > > > > > > > > > >         case NL802154_IFTYPE_NODE:
> > > > > > > > > > >                 ieee802154_be64_to_le64(&wpan_dev->extended_addr,
> > > > > > > > > > >                                         sdata->dev->dev_addr);
> > > > > > > > > > > @@ -636,6 +637,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
> > > > > > > > > > >         ieee802154_le64_to_be64(ndev->perm_addr,
> > > > > > > > > > >                                 &local->hw.phy->perm_extended_addr);
> > > > > > > > > > >         switch (type) {
> > > > > > > > > > > +       case NL802154_IFTYPE_COORD:
> > > > > > > > > > >         case NL802154_IFTYPE_NODE:
> > > > > > > > > > >                 ndev->type = ARPHRD_IEEE802154;
> > > > > > > > > > >                 if (ieee802154_is_valid_extended_unicast_addr(extended_addr)) {
> > > > > > > > > > > diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
> > > > > > > > > > > index b8ce84618a55..39459d8d787a 100644
> > > > > > > > > > > --- a/net/mac802154/rx.c
> > > > > > > > > > > +++ b/net/mac802154/rx.c
> > > > > > > > > > > @@ -203,7 +203,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > > > > > > > > >         }
> > > > > > > > > > >
> > > > > > > > > > >         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> > > > > > > > > > > -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> > > > > > > > > > > +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
> > > > > > > > > > >                         continue;  
> > > > > > > > > >
> > > > > > > > > > I probably get why you are doing that, but first the overall design is
> > > > > > > > > > working differently - means you should add an additional receive path
> > > > > > > > > > for the special interface type.
> > > > > > > > > >
> > > > > > > > > > Also we "discovered" before that the receive path of node vs
> > > > > > > > > > coordinator is different... Where is the different handling here? I
> > > > > > > > > > don't see it, I see that NODE and COORD are the same now (because that
> > > > > > > > > > is _currently_ everything else than monitor). This change is not
> > > > > > > > > > enough and does "something" to handle in some way coordinator receive
> > > > > > > > > > path but there are things missing.
> > > > > > > > > >
> > > > > > > > > > 1. Changing the address filters that it signals the transceiver it's
> > > > > > > > > > acting as coordinator
> > > > > > > > > > 2. We _should_ also have additional handling for whatever the
> > > > > > > > > > additional handling what address filters are doing in mac802154
> > > > > > > > > > _because_ there is hardware which doesn't have address filtering e.g.
> > > > > > > > > > hwsim which depend that this is working in software like other
> > > > > > > > > > transceiver hardware address filters.
> > > > > > > > > >
> > > > > > > > > > For the 2. one, I don't know if we do that even for NODE right or we
> > > > > > > > > > just have the bare minimal support there... I don't assume that
> > > > > > > > > > everything is working correctly here but what I want to see is a
> > > > > > > > > > separate receive path for coordinators that people can send patches to
> > > > > > > > > > fix it.  
> > > > > > > > >
> > > > > > > > > Yes, we do very little differently between the two modes, that's why I
> > > > > > > > > took the easy way: just changing the condition. I really don't see what
> > > > > > > > > I can currently add here, but I am fine changing the style to easily
> > > > > > > > > show people where to add filters for such or such interface, but right
> > > > > > > > > now both path will look very "identical", do we agree on that?  
> > > > > > > >
> > > > > > > > mostly yes, but there exists a difference and we should at least check
> > > > > > > > if the node receive path violates the coordinator receive path and
> > > > > > > > vice versa.
> > > > > > > > Put it in a receive_path() function and then coord_receive_path(),
> > > > > > > > node_receive_path() that calls the receive_path() and do the
> > > > > > > > additional filtering for coordinators, etc.
> > > > > > > >
> > > > > > > > There should be a part in the standard about "third level filter rule
> > > > > > > > if it's a coordinator".
> > > > > > > > btw: this is because the address filter on the transceiver needs to
> > > > > > > > have the "i am a coordinator" boolean set which is missing in this
> > > > > > > > series. However it depends on the transceiver filtering level and the
> > > > > > > > mac802154 receive path if we actually need to run such filtering or
> > > > > > > > not.  
> > > > > > >
> > > > > > > I must be missing some information because I can't find any places
> > > > > > > where what you suggest is described in the spec.
> > > > > > >
> > > > > > > I agree there are multiple filtering level so let's go through them one
> > > > > > > by one (6.7.2 Reception and rejection):
> > > > > > > - first level: is the checksum (FCS) valid?
> > > > > > >         yes -> goto second level
> > > > > > >         no -> drop
> > > > > > > - second level: are we in promiscuous mode?
> > > > > > >         yes -> forward to upper layers
> > > > > > >         no -> goto second level (bis)
> > > > > > > - second level (bis): are we scanning?
> > > > > > >         yes -> goto scan filtering
> > > > > > >         no -> goto third level
> > > > > > > - scan filtering: is it a beacon?
> > > > > > >         yes -> process the beacon
> > > > > > >         no -> drop
> > > > > > > - third level: is the frame valid? (type, source, destination, pan id,
> > > > > > >   etc)
> > > > > > >         yes -> forward to upper layers
> > > > > > >         no -> drop
> > > > > > >
> > > > > > > But none of them, as you said, is dependent on the interface type.
> > > > > > > There is no mention of a specific filtering operation to do in all
> > > > > > > those cases when running in COORD mode. So I still don't get what
> > > > > > > should be included in either node_receive_path() which should be
> > > > > > > different than in coord_receive_path() for now.
> > > > > > >
> > > > > > > There are, however, two situations where the interface type has its
> > > > > > > importance:
> > > > > > > - Enhanced beacon requests with Enhanced beacon filter IE, which asks
> > > > > > >   the receiving device to process/drop the request upon certain
> > > > > > >   conditions (minimum LQI and/or randomness), as detailed in
> > > > > > >   7.4.4.6 Enhanced Beacon Filter IE. But, as mentioned in
> > > > > > >   7.5.9 Enhanced Beacon Request command: "The Enhanced Beacon Request
> > > > > > >   command is optional for an FFD and an RFD", so this series was only
> > > > > > >   targeting basic beaconing for now.
> > > > > > > - In relaying mode, the destination address must not be validated
> > > > > > >   because the message needs to be re-emitted. Indeed, a receiver in
> > > > > > >   relaying mode may not be the recipient. This is also optional and out
> > > > > > >   of the scope of this series.
> > > > > > >
> > > > > > > Right now I have the below diff, which clarifies the two path, without
> > > > > > > too much changes in the current code because I don't really see why it
> > > > > > > would be necessary. Unless you convince me otherwise or read the spec
> > > > > > > differently than I do :) What do you think?
> > > > > > >  
> > > > > >
> > > > > > "Reception and rejection"
> > > > > >
> > > > > > third-level filtering regarding "destination address" and if the
> > > > > > device is "PAN coordinator".
> > > > > > This is, in my opinion, what the coordinator boolean tells the
> > > > > > transceiver to do on hardware when doing address filter there. You can
> > > > > > also read that up in datasheets of transceivers as atf86rf233, search
> > > > > > for I_AM_COORD.  
> > > > >
> > > > > Oh right, I now see what you mean!
> > > > >  
> > > > > > Whereas they use the word "PAN coordinator" not "coordinator", if they
> > > > > > really make a difference there at this point..., if so then the kernel
> > > > > > must know if the coordinator is a pan coordinator or coordinator
> > > > > > because we need to set the address filter in kernel.  
> > > > >
> > > > > Yes we need to make a difference, you can have several coordinators but
> > > > > a single PAN coordinator in a PAN. I think we can assume that the PAN
> > > > > coordinator is the coordinator with no parent (association-wise). With
> > > > > the addition of the association series, I can handle that, so I will
> > > > > create the two path as you advise, add a comment about this additional
> > > > > filter rule that we don't yet support, and finally after the
> > > > > association series add another commit to make this filtering rule real.
> > > > >  
> > > > > >  
> > > > > > > Thanks,
> > > > > > > Miquèl
> > > > > > >
> > > > > > > ---
> > > > > > >
> > > > > > > --- a/net/mac802154/rx.c
> > > > > > > +++ b/net/mac802154/rx.c
> > > > > > > @@ -194,6 +194,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > > > > >         int ret;
> > > > > > >         struct ieee802154_sub_if_data *sdata;
> > > > > > >         struct ieee802154_hdr hdr;
> > > > > > > +       bool iface_found = false;
> > > > > > >
> > > > > > >         ret = ieee802154_parse_frame_start(skb, &hdr);
> > > > > > >         if (ret) {
> > > > > > > @@ -203,18 +204,31 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
> > > > > > >         }
> > > > > > >
> > > > > > >         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> > > > > > > -               if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
> > > > > > > +               if (sdata->wpan_dev.iftype == NL802154_IFTYPE_MONITOR)
> > > > > > >                         continue;
> > > > > > >
> > > > > > >                 if (!ieee802154_sdata_running(sdata))
> > > > > > >                         continue;
> > > > > > >
> > > > > > > +               iface_found = true;
> > > > > > > +               break;
> > > > > > > +       }
> > > > > > > +
> > > > > > > +       if (!iface_found) {
> > > > > > > +               kfree_skb(skb);
> > > > > > > +               return;
> > > > > > > +       }
> > > > > > > +
> > > > > > > +       /* TBD: Additional filtering is possible on NODEs and/or COORDINATORs */
> > > > > > > +       switch (sdata->wpan_dev.iftype) {
> > > > > > > +       case NL802154_IFTYPE_COORD:
> > > > > > > +       case NL802154_IFTYPE_NODE:
> > > > > > >                 ieee802154_subif_frame(sdata, skb, &hdr);
> > > > > > > -               skb = NULL;
> > > > > > > +               break;
> > > > > > > +       default:
> > > > > > > +               kfree_skb(skb);
> > > > > > >                 break;
> > > > > > >         }  
> > > > > >
> > > > > > Why do you remove the whole interface looping above and make it only
> > > > > > run for one ?first found? ?  
> > > > >
> > > > > To reduce the indentation level.
> > > > >  
> > > > > > That code changes this behaviour and I do
> > > > > > not know why.  
> > > > >
> > > > > The precedent code did:
> > > > > for_each_iface() {
> > > > >         if (not a node)
> > > > >                 continue;
> > > > >         if (not running)
> > > > >                 continue;
> > > > >
> > > > >         subif_frame();
> > > > >         break;
> > > > > }
> > > > >
> > > > > That final break also elected only the first running node iface.
> > > > > Otherwise it would mean that we allow the same skb to be consumed
> > > > > twice, which is wrong IMHO?  
> > > >
> > > > no? Why is that wrong? There is a real use-case to have multiple
> > > > interfaces on one phy (or to do it in near future, I said that
> > > > multiple times). This patch does a step backwards to this.  
> > >
> > > So we need to duplicate the skb because it automatically gets freed in
> > > the "forward to upper layer" path. Am I right? I'm fine doing so if  
> >
> > What is the definition of "duplicate the skb" here.
> >  
> > > this is the way to go, but I am interested if you can give me a real
> > > use case where having NODE+COORDINATOR on the same PHY is useful?
> > >  
> >
> > Testing.  
> 
> I need to say that I really used multiple monitors at the same time on
> one phy only and I did that with hwsim to run multiple user space
> stacks. It was working and I was happy and didn't need to do a lot of
> phy creations in hwsim.

Indeed, looking at the code, you could use as many MONITOR interfaces
you needed, but only a single NODE. I've changed that to use as many
NODE and COORD that we wish.

> Most hardware can probably not run multiple
> nodes and coordinators at the same time ?yet?, _but_ there is a
> candidate which can do that and this is atusb. On atusb we have a
> co-processor that can deal with multiple address filters. People
> already asked to do something like a node which can operate on two
> pans as I remember, that would be a candidate for such a feature.

Oh nice! Yes this makes sense.

> I
> really don't want to move step backwards here and delete this thing
> which probably can be useful later. I don't know how wireless history
> dealt with it and how complicated it was to bring such a feature in to
> e.g. run multiple access points on one phy. I also see it in ethernet
> with macvlan, which is a similar feature.
> 
> We don't need to support it, make it so that on an ifup it returns
> -EBUSY if something doesn't fit together as it currently is. We can
> later add support for it after playing around with hwsim a little bit
> more. We should at least take care that I can still run my multiple
> monitors at the same time (which is currently allowed).
> 
> - Alex
> 


Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-26  8:08                       ` Miquel Raynal
@ 2022-08-29  2:31                         ` Alexander Aring
  2022-08-29  8:05                           ` Miquel Raynal
  0 siblings, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-08-29  2:31 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Fri, Aug 26, 2022 at 4:08 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
...
> >
> > I need to say that I really used multiple monitors at the same time on
> > one phy only and I did that with hwsim to run multiple user space
> > stacks. It was working and I was happy and didn't need to do a lot of
> > phy creations in hwsim.
>
> Indeed, looking at the code, you could use as many MONITOR interfaces
> you needed, but only a single NODE. I've changed that to use as many
> NODE and COORD that we wish.
>

Be careful there, there is a reason why we don't allow this and this
has to do with support of multiple address filters... but here it
depends also what you mean with "use".

I need to admit, you can achieve the same behaviour of multiple user
space stacks and one monitor, _but_ you can easily filter the traffic
if you do it per interface...

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-26  7:54                         ` Miquel Raynal
@ 2022-08-29  2:52                           ` Alexander Aring
  2022-08-29  8:02                             ` Miquel Raynal
  0 siblings, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-08-29  2:52 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Fri, Aug 26, 2022 at 3:54 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> Hi Alexander,
>
> aahringo@redhat.com wrote on Thu, 25 Aug 2022 21:05:09 -0400:
>
> > Hi,
> >
> > On Thu, Aug 25, 2022 at 8:58 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > >
> > > Hi Alexander,
> > >
> > > aahringo@redhat.com wrote on Wed, 24 Aug 2022 17:53:45 -0400:
> > >
> > > > Hi,
> > > >
> > > > On Wed, Aug 24, 2022 at 9:27 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > > >
> > > > > Hi Alexander,
> > > > >
> > > > > aahringo@redhat.com wrote on Wed, 24 Aug 2022 08:43:20 -0400:
> > > > >
> > > > > > Hi,
> > > > > >
> > > > > > On Wed, Aug 24, 2022 at 6:21 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > > > > ...
> > > > > > >
> > > > > > > Actually right now the second level is not enforced, and all the
> > > > > > > filtering levels are a bit fuzzy and spread everywhere in rx.c.
> > > > > > >
> > > > > > > I'm gonna see if I can at least clarify all of that and only make
> > > > > > > coord-dependent the right section because right now a
> > > > > > > ieee802154_coord_rx() path in ieee802154_rx_handle_packet() does not
> > > > > > > really make sense given that the level 3 filtering rules are mostly
> > > > > > > enforced in ieee802154_subif_frame().
> > > > > >
> > > > > > One thing I mentioned before is that we probably like to have a
> > > > > > parameter for rx path to give mac802154 a hint on which filtering
> > > > > > level it was received. We don't have that, I currently see that this
> > > > > > is a parameter for hwsim receiving it on promiscuous level only and
> > > > > > all others do third level filtering.
> > > > > > We need that now, because the promiscuous mode was only used for
> > > > > > sniffing which goes directly into the rx path for monitors. With scan
> > > > > > we mix things up here and in my opinion require such a parameter and
> > > > > > do filtering if necessary.
> > > > >
> > > > > I am currently trying to implement a slightly different approach. The
> > > > > core does not know hwsim is always in promiscuous mode, but it does
> > > > > know that it does not check FCS. So the core checks it. This is
> > > > > level 1 achieved. Then in level 2 we want to know if the core asked
> > > > > the transceiver to enter promiscuous mode, which, if it did, should
> > > > > not imply more filtering. If the device is working in promiscuous
> > > > > mode but this was not asked explicitly by the core, we don't really
> > > > > care, software filtering will apply anyway.
> > > > >
> > > >
> > > > I doubt that I will be happy with this solution, this all sounds like
> > > > "for the specific current behaviour that we support 2 filtering levels
> > > > it will work", just do a parameter on which 802.15.4 filtering level
> > > > it was received and the rx path will check what kind of filter is
> > > > required and which not.
> > > > As driver ops start() callback you should say which filtering level
> > > > the receive mode should start with.
> > > >
> > > > > I am reworking the rx path to clarify what is being done and when,
> > > > > because I found this part very obscure right now. In the end I don't
> > > > > think we need additional rx info from the drivers. Hopefully my
> > > > > proposal will clarify why this is (IMHO) not needed.
> > > > >
> > > >
> > > > Never looked much in 802.15.4 receive path as it just worked but I
> > > > said that there might be things to clean up when filtering things on
> > > > hardware and when on software and I have the feeling we are doing
> > > > things twice. Sometimes it is also necessary to set some skb fields
> > > > e.g. PACKET_HOST, etc. and I think this is what the most important
> > > > part of it is there. However, there are probably some tune ups if we
> > > > know we are in third leveling filtering...
> > >
> > > Ok, I've done the following.
> > >
> > > - Adding a PHY parameter which reflects the actual filtering level of
> > >   the transceiver, the default level is 4 (standard situation, you're
> >
> > 3?
>
> Honestly there are only two filtering levels in the normal path and one
> additional for scanning situations. But the spec mentions 4, so I
> figured we should use the same naming to avoid confusing people on what
> "level 3 means, if it's level 3 because level 1 and 2 are identical at
> PHY level, or level 3 which is the scan filtering as mentioned in the
> spec?".
>
> I used this enum to clarify the amount of filtering that is involved,
> hopefully it is clear enough. I remember we talked about this already
> but an unrelated thread, and was not capable of finding it anymore O:-).
>
> /** enum ieee802154_filtering_level - Filtering levels applicable to a PHY
>  * @IEEE802154_FILTERING_NONE: No filtering at all, what is received is
>  *      forwarded to the softMAC
>  * @IEEE802154_FILTERING_1_FCS: First filtering level, frames with an invalid
>  *      FCS should be dropped
>  * @IEEE802154_FILTERING_2_PROMISCUOUS: Second filtering level, promiscuous
>  *      mode, identical in terms of filtering to the first level at the PHY
>  *      level, but no ACK should be transmitted automatically and at the MAC
>  *      level the frame should be forwarded to the upper layer directly
>  * @IEEE802154_FILTERING_3_SCAN: Third filtering level, enforced during scans,
>  *      which only forwards beacons
>  * @IEEE802154_FILTERING_4_FRAME_FIELDS: Fourth filtering level actually
>  *      enforcing the validity of the content of the frame with various checks
>  */
> enum ieee802154_filtering_level {
>         IEEE802154_FILTERING_NONE,
>         IEEE802154_FILTERING_1_FCS,
>         IEEE802154_FILTERING_2_PROMISCUOUS,
>         IEEE802154_FILTERING_3_SCAN,
>         IEEE802154_FILTERING_4_FRAME_FIELDS,
> };
>

I am fine to drop all this level number naming at all and we do our
own filtering definition here, additionally to the mandatory ones.
E.g. The SCAN filter can also be implemented in e.g. atusb by using
other filter modes which are based on 802.15.4 modes (or level
whatever).

I am currently thinking about if we might need to change something
here in the default handling of the monitor interface, it should use
802.15.4 compatible modes (and this is what we should expect is always
being supported). IEEE802154_FILTERING_NONE is not a 802.15.4
filtering mode and is considered to be optional. So the default
behaviour of the monitor should be IEEE802154_FILTERING_FCS with a
possibility to have a switch to change to IEEE802154_FILTERING_NONE
mode if it's supported by the hardware.

You should also add a note on the filter level/modes which are
mandatory (means given by the spec) and put their level inside there?

> >
> > >   receiving data) but of course if the PHY does not support this state
> > >   (like hwsim) it should overwrite this value by setting the actual
> > >   filtering level (none, in the hwsim case) so that the core knows what
> > >   it receives.
> > >
> >
> > ok.
> >
> > > - I've replaced the specific "do not check the FCS" flag only used by
> > >   hwsim by this filtering level, which gives all the information we
> > >   need.
> > >
> >
> > ok.
> >
> > > - I've added a real promiscuous filtering mode which truly does not
> > >   care about the content of the frame but only checks the FCS if not
> > >   already done by the xceiver.
> > >
> >
> > not sure what a "real promiscuous filtering here is" people have
> > different understanding about it, but 802.15.4 has a definition for
> > it.
>
> Promiscuous, by the 802154 spec means: the FCS is good so the content of
> the received packet must means something, just forward it and let upper
> layers handle it.
>
> Until now there was no real promiscuous mode in the mac NODE rx path.
> Only monitors would get all the frames (including the ones with a wrong
> FCS), which is fine because it's a bit out of the spec, so I'm fine
> with this idea. But otherwise in the NODE/COORD rx path, the FCS should
> be checked even in promiscuous mode to correctly match the spec.
>

If we parse the frame, the FCS should always be checked. The frame
should _never_ be parsed before it hits the monitor receive path.

The wording "real promiscuous mode" is in my opinion still debatable,
however that's not the point here.

> Until now, ieee802154_parse_frame_start() was always called in these
> path and this would validate the frame headers. I've added a more
> precise promiscuous mode in the rx patch which skips any additional
> checks. What happens however is that, if the transceiver disables FCS
> checks in promiscuous mode, then FCS is not checked at all and this is
> invalid. With my current implementation, the devices which do not check
> the FCS might be easily "fixed" by changing their PHY filtering level
> to "FILTERING_NONE" in the promiscuous callback.
>
> > You should consider that having monitors, frames with bad fcs
> > should not be filtered out by hardware. There it comes back what I
> > said before, the filtering level should be a parameter for start()
> > driver ops.
> >
> > > - I've also implemented in software filtering level 4 for most
> > > regular
> >
> > 3?
> >
> > >   data packets. Without changing the default PHY level mentioned in
> > > the first item above, this additional filtering will be skipped
> > > which ensures we keep the same behavior of most driver. In the case
> > > of hwsim however, these filters will become active if the MAC is
> > > not in promiscuous mode or in scan mode, which is actually what
> > > people should be expecting.
> > >
> >
> > To give feedback to that I need to see code. And please don't send the
> > whole feature stuff again, just this specific part of it. Thanks.
>
> The entire filtering feature is split: there are the basis introduced
> before the scan, and then after the whole scan+association thing I've
> introduced additional filtering levels.
>

No idea what that means.

> > > Hopefully all this fits what you had in mind.
> > >
> > > I have one item left on my current todo list: improving a bit the
> > > userspace tool with a "monitor" command.
> > >
> > > Otherwise the remaining things to do are to discuss the locking
> > > design which might need to be changed to avoid lockdep issues and
> > > keep the rtnl locked eg. during a channel change. I still don't
> > > know how to do that, so it's likely that the right next version
> > > will not include any change in this area unless something pops up.
> >
> > I try to look at that on the weekend.
>
> I've had an idea yesterday night which seem to work, I think I can drop
> the two patches which you disliked regarding discarding the rtnl in the
> tx path and in hwsim:change_channel().

I would like to bring the filtering level question at first upstream.
If you don't mind.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-29  2:52                           ` Alexander Aring
@ 2022-08-29  8:02                             ` Miquel Raynal
  2022-08-30  2:23                               ` Alexander Aring
  0 siblings, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-08-29  8:02 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Sun, 28 Aug 2022 22:52:14 -0400:

> Hi,
> 
> On Fri, Aug 26, 2022 at 3:54 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> >
> > Hi Alexander,
> >
> > aahringo@redhat.com wrote on Thu, 25 Aug 2022 21:05:09 -0400:
> >  
> > > Hi,
> > >
> > > On Thu, Aug 25, 2022 at 8:58 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > > >
> > > > Hi Alexander,
> > > >
> > > > aahringo@redhat.com wrote on Wed, 24 Aug 2022 17:53:45 -0400:
> > > >  
> > > > > Hi,
> > > > >
> > > > > On Wed, Aug 24, 2022 at 9:27 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:  
> > > > > >
> > > > > > Hi Alexander,
> > > > > >
> > > > > > aahringo@redhat.com wrote on Wed, 24 Aug 2022 08:43:20 -0400:
> > > > > >  
> > > > > > > Hi,
> > > > > > >
> > > > > > > On Wed, Aug 24, 2022 at 6:21 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > > > > > ...  
> > > > > > > >
> > > > > > > > Actually right now the second level is not enforced, and all the
> > > > > > > > filtering levels are a bit fuzzy and spread everywhere in rx.c.
> > > > > > > >
> > > > > > > > I'm gonna see if I can at least clarify all of that and only make
> > > > > > > > coord-dependent the right section because right now a
> > > > > > > > ieee802154_coord_rx() path in ieee802154_rx_handle_packet() does not
> > > > > > > > really make sense given that the level 3 filtering rules are mostly
> > > > > > > > enforced in ieee802154_subif_frame().  
> > > > > > >
> > > > > > > One thing I mentioned before is that we probably like to have a
> > > > > > > parameter for rx path to give mac802154 a hint on which filtering
> > > > > > > level it was received. We don't have that, I currently see that this
> > > > > > > is a parameter for hwsim receiving it on promiscuous level only and
> > > > > > > all others do third level filtering.
> > > > > > > We need that now, because the promiscuous mode was only used for
> > > > > > > sniffing which goes directly into the rx path for monitors. With scan
> > > > > > > we mix things up here and in my opinion require such a parameter and
> > > > > > > do filtering if necessary.  
> > > > > >
> > > > > > I am currently trying to implement a slightly different approach. The
> > > > > > core does not know hwsim is always in promiscuous mode, but it does
> > > > > > know that it does not check FCS. So the core checks it. This is
> > > > > > level 1 achieved. Then in level 2 we want to know if the core asked
> > > > > > the transceiver to enter promiscuous mode, which, if it did, should
> > > > > > not imply more filtering. If the device is working in promiscuous
> > > > > > mode but this was not asked explicitly by the core, we don't really
> > > > > > care, software filtering will apply anyway.
> > > > > >  
> > > > >
> > > > > I doubt that I will be happy with this solution, this all sounds like
> > > > > "for the specific current behaviour that we support 2 filtering levels
> > > > > it will work", just do a parameter on which 802.15.4 filtering level
> > > > > it was received and the rx path will check what kind of filter is
> > > > > required and which not.
> > > > > As driver ops start() callback you should say which filtering level
> > > > > the receive mode should start with.
> > > > >  
> > > > > > I am reworking the rx path to clarify what is being done and when,
> > > > > > because I found this part very obscure right now. In the end I don't
> > > > > > think we need additional rx info from the drivers. Hopefully my
> > > > > > proposal will clarify why this is (IMHO) not needed.
> > > > > >  
> > > > >
> > > > > Never looked much in 802.15.4 receive path as it just worked but I
> > > > > said that there might be things to clean up when filtering things on
> > > > > hardware and when on software and I have the feeling we are doing
> > > > > things twice. Sometimes it is also necessary to set some skb fields
> > > > > e.g. PACKET_HOST, etc. and I think this is what the most important
> > > > > part of it is there. However, there are probably some tune ups if we
> > > > > know we are in third leveling filtering...  
> > > >
> > > > Ok, I've done the following.
> > > >
> > > > - Adding a PHY parameter which reflects the actual filtering level of
> > > >   the transceiver, the default level is 4 (standard situation, you're  
> > >
> > > 3?  
> >
> > Honestly there are only two filtering levels in the normal path and one
> > additional for scanning situations. But the spec mentions 4, so I
> > figured we should use the same naming to avoid confusing people on what
> > "level 3 means, if it's level 3 because level 1 and 2 are identical at
> > PHY level, or level 3 which is the scan filtering as mentioned in the
> > spec?".
> >
> > I used this enum to clarify the amount of filtering that is involved,
> > hopefully it is clear enough. I remember we talked about this already
> > but an unrelated thread, and was not capable of finding it anymore O:-).
> >
> > /** enum ieee802154_filtering_level - Filtering levels applicable to a PHY
> >  * @IEEE802154_FILTERING_NONE: No filtering at all, what is received is
> >  *      forwarded to the softMAC
> >  * @IEEE802154_FILTERING_1_FCS: First filtering level, frames with an invalid
> >  *      FCS should be dropped
> >  * @IEEE802154_FILTERING_2_PROMISCUOUS: Second filtering level, promiscuous
> >  *      mode, identical in terms of filtering to the first level at the PHY
> >  *      level, but no ACK should be transmitted automatically and at the MAC
> >  *      level the frame should be forwarded to the upper layer directly
> >  * @IEEE802154_FILTERING_3_SCAN: Third filtering level, enforced during scans,
> >  *      which only forwards beacons
> >  * @IEEE802154_FILTERING_4_FRAME_FIELDS: Fourth filtering level actually
> >  *      enforcing the validity of the content of the frame with various checks
> >  */
> > enum ieee802154_filtering_level {
> >         IEEE802154_FILTERING_NONE,
> >         IEEE802154_FILTERING_1_FCS,
> >         IEEE802154_FILTERING_2_PROMISCUOUS,
> >         IEEE802154_FILTERING_3_SCAN,
> >         IEEE802154_FILTERING_4_FRAME_FIELDS,
> > };
> >  
> 
> I am fine to drop all this level number naming at all and we do our
> own filtering definition here, additionally to the mandatory ones.

I can add intermediate filtering levels but I don't know what they are,
you need to give me an exhaustive list of what you have in mind?

> E.g. The SCAN filter can also be implemented in e.g. atusb by using
> other filter modes which are based on 802.15.4 modes (or level
> whatever).

That is actually what I've proposed. The core requests a level of
filtering among the official ones, the PHY driver when it gets the
request does what is possible and adjusts the final filtering level to
what it achieved. The core will then have to handle the missing checks.

> I am currently thinking about if we might need to change something
> here in the default handling of the monitor interface, it should use
> 802.15.4 compatible modes (and this is what we should expect is always
> being supported). IEEE802154_FILTERING_NONE is not a 802.15.4
> filtering mode and is considered to be optional. So the default
> behaviour of the monitor should be IEEE802154_FILTERING_FCS with a
> possibility to have a switch to change to IEEE802154_FILTERING_NONE
> mode if it's supported by the hardware.

That's what I've done, besides that the default filtering level for a
monitor interface is PROMISCUOUS and not FCS. In practice, the
filtering regarding the incoming frames will be exactly the same
between FCS, PROMISCUOUS and SCAN, but in the PROMISCUOUS case we ask
the PHY not to send ACKS (which is not the case of the FCS filtering
level, acks can be automatically sent by the PHY, we don't want that).

> You should also add a note on the filter level/modes which are
> mandatory (means given by the spec) and put their level inside there?
> 
> > >  
> > > >   receiving data) but of course if the PHY does not support
> > > > this state (like hwsim) it should overwrite this value by
> > > > setting the actual filtering level (none, in the hwsim case) so
> > > > that the core knows what it receives.
> > > >  
> > >
> > > ok.
> > >  
> > > > - I've replaced the specific "do not check the FCS" flag only
> > > > used by hwsim by this filtering level, which gives all the
> > > > information we need.
> > > >  
> > >
> > > ok.
> > >  
> > > > - I've added a real promiscuous filtering mode which truly does
> > > > not care about the content of the frame but only checks the FCS
> > > > if not already done by the xceiver.
> > > >  
> > >
> > > not sure what a "real promiscuous filtering here is" people have
> > > different understanding about it, but 802.15.4 has a definition
> > > for it.  
> >
> > Promiscuous, by the 802154 spec means: the FCS is good so the
> > content of the received packet must means something, just forward
> > it and let upper layers handle it.
> >
> > Until now there was no real promiscuous mode in the mac NODE rx
> > path. Only monitors would get all the frames (including the ones
> > with a wrong FCS), which is fine because it's a bit out of the
> > spec, so I'm fine with this idea. But otherwise in the NODE/COORD
> > rx path, the FCS should be checked even in promiscuous mode to
> > correctly match the spec. 
> 
> If we parse the frame, the FCS should always be checked. The frame
> should _never_ be parsed before it hits the monitor receive path.

Yes.

> 
> The wording "real promiscuous mode" is in my opinion still debatable,
> however that's not the point here.

I meant "like it is described in the spec".

> > Until now, ieee802154_parse_frame_start() was always called in these
> > path and this would validate the frame headers. I've added a more
> > precise promiscuous mode in the rx patch which skips any additional
> > checks. What happens however is that, if the transceiver disables
> > FCS checks in promiscuous mode, then FCS is not checked at all and
> > this is invalid. With my current implementation, the devices which
> > do not check the FCS might be easily "fixed" by changing their PHY
> > filtering level to "FILTERING_NONE" in the promiscuous callback.
> >  
> > > You should consider that having monitors, frames with bad fcs
> > > should not be filtered out by hardware. There it comes back what I
> > > said before, the filtering level should be a parameter for start()
> > > driver ops.
> > >  
> > > > - I've also implemented in software filtering level 4 for most
> > > > regular  
> > >
> > > 3?
> > >  
> > > >   data packets. Without changing the default PHY level
> > > > mentioned in the first item above, this additional filtering
> > > > will be skipped which ensures we keep the same behavior of most
> > > > driver. In the case of hwsim however, these filters will become
> > > > active if the MAC is not in promiscuous mode or in scan mode,
> > > > which is actually what people should be expecting.
> > > >  
> > >
> > > To give feedback to that I need to see code. And please don't
> > > send the whole feature stuff again, just this specific part of
> > > it. Thanks.  
> >
> > The entire filtering feature is split: there are the basis
> > introduced before the scan, and then after the whole
> > scan+association thing I've introduced additional filtering levels.
> >  
> 
> No idea what that means.

In my series, the first patches address the missing bits about
filtering. Then there are patches about the scan. And finally there are
two patches improving the filtering, which are not actually needed
right now for the scan to work.

> > > > Hopefully all this fits what you had in mind.
> > > >
> > > > I have one item left on my current todo list: improving a bit
> > > > the userspace tool with a "monitor" command.
> > > >
> > > > Otherwise the remaining things to do are to discuss the locking
> > > > design which might need to be changed to avoid lockdep issues
> > > > and keep the rtnl locked eg. during a channel change. I still
> > > > don't know how to do that, so it's likely that the right next
> > > > version will not include any change in this area unless
> > > > something pops up.  
> > >
> > > I try to look at that on the weekend.  
> >
> > I've had an idea yesterday night which seem to work, I think I can
> > drop the two patches which you disliked regarding discarding the
> > rtnl in the tx path and in hwsim:change_channel().  
> 
> I would like to bring the filtering level question at first upstream.
> If you don't mind.

The additional filtering which I've written has nothing to do with the
scan, and more importantly it uses many new enums/helpers which are
added along the way (by the scan series and the association series).
Hence moving this filtering earlier in the series is a real pain and
would anyway not bring anything really useful at this stage. All the
important filtering changes are already available in the v2 series sent
last week.

Not mentioning, I would really like to move forward on the scan series
as it's been in the air for quite some time.

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-29  2:31                         ` Alexander Aring
@ 2022-08-29  8:05                           ` Miquel Raynal
  0 siblings, 0 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-08-29  8:05 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Sun, 28 Aug 2022 22:31:19 -0400:

> Hi,
> 
> On Fri, Aug 26, 2022 at 4:08 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> ...
> > >
> > > I need to say that I really used multiple monitors at the same time on
> > > one phy only and I did that with hwsim to run multiple user space
> > > stacks. It was working and I was happy and didn't need to do a lot of
> > > phy creations in hwsim.  
> >
> > Indeed, looking at the code, you could use as many MONITOR interfaces
> > you needed, but only a single NODE. I've changed that to use as many
> > NODE and COORD that we wish.
> >  
> 
> Be careful there, there is a reason why we don't allow this and this
> has to do with support of multiple address filters... but here it
> depends also what you mean with "use".

I've updated this part, you're right I was not careful enough on the
per-iface filtering part, I think it's fine now. Basically, compared to
the v2 sent last week, I've stopped considering that if one interface
was in promiscuous mode, all of them should and did a per-PHY check, so
that otherwise we can apply the necessary filtering if needed.

> I need to admit, you can achieve the same behaviour of multiple user
> space stacks and one monitor, _but_ you can easily filter the traffic
> if you do it per interface...

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-29  8:02                             ` Miquel Raynal
@ 2022-08-30  2:23                               ` Alexander Aring
  2022-08-31 15:39                                 ` Miquel Raynal
  0 siblings, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-08-30  2:23 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Mon, Aug 29, 2022 at 4:02 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> Hi Alexander,
>
> aahringo@redhat.com wrote on Sun, 28 Aug 2022 22:52:14 -0400:
>
> > Hi,
> >
> > On Fri, Aug 26, 2022 at 3:54 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > >
> > > Hi Alexander,
> > >
> > > aahringo@redhat.com wrote on Thu, 25 Aug 2022 21:05:09 -0400:
> > >
> > > > Hi,
> > > >
> > > > On Thu, Aug 25, 2022 at 8:58 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > > >
> > > > > Hi Alexander,
> > > > >
> > > > > aahringo@redhat.com wrote on Wed, 24 Aug 2022 17:53:45 -0400:
> > > > >
> > > > > > Hi,
> > > > > >
> > > > > > On Wed, Aug 24, 2022 at 9:27 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > > > > >
> > > > > > > Hi Alexander,
> > > > > > >
> > > > > > > aahringo@redhat.com wrote on Wed, 24 Aug 2022 08:43:20 -0400:
> > > > > > >
> > > > > > > > Hi,
> > > > > > > >
> > > > > > > > On Wed, Aug 24, 2022 at 6:21 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > > > > > > ...
> > > > > > > > >
> > > > > > > > > Actually right now the second level is not enforced, and all the
> > > > > > > > > filtering levels are a bit fuzzy and spread everywhere in rx.c.
> > > > > > > > >
> > > > > > > > > I'm gonna see if I can at least clarify all of that and only make
> > > > > > > > > coord-dependent the right section because right now a
> > > > > > > > > ieee802154_coord_rx() path in ieee802154_rx_handle_packet() does not
> > > > > > > > > really make sense given that the level 3 filtering rules are mostly
> > > > > > > > > enforced in ieee802154_subif_frame().
> > > > > > > >
> > > > > > > > One thing I mentioned before is that we probably like to have a
> > > > > > > > parameter for rx path to give mac802154 a hint on which filtering
> > > > > > > > level it was received. We don't have that, I currently see that this
> > > > > > > > is a parameter for hwsim receiving it on promiscuous level only and
> > > > > > > > all others do third level filtering.
> > > > > > > > We need that now, because the promiscuous mode was only used for
> > > > > > > > sniffing which goes directly into the rx path for monitors. With scan
> > > > > > > > we mix things up here and in my opinion require such a parameter and
> > > > > > > > do filtering if necessary.
> > > > > > >
> > > > > > > I am currently trying to implement a slightly different approach. The
> > > > > > > core does not know hwsim is always in promiscuous mode, but it does
> > > > > > > know that it does not check FCS. So the core checks it. This is
> > > > > > > level 1 achieved. Then in level 2 we want to know if the core asked
> > > > > > > the transceiver to enter promiscuous mode, which, if it did, should
> > > > > > > not imply more filtering. If the device is working in promiscuous
> > > > > > > mode but this was not asked explicitly by the core, we don't really
> > > > > > > care, software filtering will apply anyway.
> > > > > > >
> > > > > >
> > > > > > I doubt that I will be happy with this solution, this all sounds like
> > > > > > "for the specific current behaviour that we support 2 filtering levels
> > > > > > it will work", just do a parameter on which 802.15.4 filtering level
> > > > > > it was received and the rx path will check what kind of filter is
> > > > > > required and which not.
> > > > > > As driver ops start() callback you should say which filtering level
> > > > > > the receive mode should start with.
> > > > > >
> > > > > > > I am reworking the rx path to clarify what is being done and when,
> > > > > > > because I found this part very obscure right now. In the end I don't
> > > > > > > think we need additional rx info from the drivers. Hopefully my
> > > > > > > proposal will clarify why this is (IMHO) not needed.
> > > > > > >
> > > > > >
> > > > > > Never looked much in 802.15.4 receive path as it just worked but I
> > > > > > said that there might be things to clean up when filtering things on
> > > > > > hardware and when on software and I have the feeling we are doing
> > > > > > things twice. Sometimes it is also necessary to set some skb fields
> > > > > > e.g. PACKET_HOST, etc. and I think this is what the most important
> > > > > > part of it is there. However, there are probably some tune ups if we
> > > > > > know we are in third leveling filtering...
> > > > >
> > > > > Ok, I've done the following.
> > > > >
> > > > > - Adding a PHY parameter which reflects the actual filtering level of
> > > > >   the transceiver, the default level is 4 (standard situation, you're
> > > >
> > > > 3?
> > >
> > > Honestly there are only two filtering levels in the normal path and one
> > > additional for scanning situations. But the spec mentions 4, so I
> > > figured we should use the same naming to avoid confusing people on what
> > > "level 3 means, if it's level 3 because level 1 and 2 are identical at
> > > PHY level, or level 3 which is the scan filtering as mentioned in the
> > > spec?".
> > >
> > > I used this enum to clarify the amount of filtering that is involved,
> > > hopefully it is clear enough. I remember we talked about this already
> > > but an unrelated thread, and was not capable of finding it anymore O:-).
> > >
> > > /** enum ieee802154_filtering_level - Filtering levels applicable to a PHY
> > >  * @IEEE802154_FILTERING_NONE: No filtering at all, what is received is
> > >  *      forwarded to the softMAC
> > >  * @IEEE802154_FILTERING_1_FCS: First filtering level, frames with an invalid
> > >  *      FCS should be dropped
> > >  * @IEEE802154_FILTERING_2_PROMISCUOUS: Second filtering level, promiscuous
> > >  *      mode, identical in terms of filtering to the first level at the PHY
> > >  *      level, but no ACK should be transmitted automatically and at the MAC
> > >  *      level the frame should be forwarded to the upper layer directly
> > >  * @IEEE802154_FILTERING_3_SCAN: Third filtering level, enforced during scans,
> > >  *      which only forwards beacons
> > >  * @IEEE802154_FILTERING_4_FRAME_FIELDS: Fourth filtering level actually
> > >  *      enforcing the validity of the content of the frame with various checks
> > >  */
> > > enum ieee802154_filtering_level {
> > >         IEEE802154_FILTERING_NONE,
> > >         IEEE802154_FILTERING_1_FCS,
> > >         IEEE802154_FILTERING_2_PROMISCUOUS,
> > >         IEEE802154_FILTERING_3_SCAN,
> > >         IEEE802154_FILTERING_4_FRAME_FIELDS,
> > > };
> > >
> >
> > I am fine to drop all this level number naming at all and we do our
> > own filtering definition here, additionally to the mandatory ones.
>
> I can add intermediate filtering levels but I don't know what they are,
> you need to give me an exhaustive list of what you have in mind?
>

see below.

> > E.g. The SCAN filter can also be implemented in e.g. atusb by using
> > other filter modes which are based on 802.15.4 modes (or level
> > whatever).
>
> That is actually what I've proposed. The core requests a level of
> filtering among the official ones, the PHY driver when it gets the
> request does what is possible and adjusts the final filtering level to
> what it achieved. The core will then have to handle the missing checks.
>

We talked about the same thing months ago.

I am fine with that, but see below.

> > I am currently thinking about if we might need to change something
> > here in the default handling of the monitor interface, it should use
> > 802.15.4 compatible modes (and this is what we should expect is always
> > being supported). IEEE802154_FILTERING_NONE is not a 802.15.4
> > filtering mode and is considered to be optional. So the default
> > behaviour of the monitor should be IEEE802154_FILTERING_FCS with a
> > possibility to have a switch to change to IEEE802154_FILTERING_NONE
> > mode if it's supported by the hardware.
>
> That's what I've done, besides that the default filtering level for a
> monitor interface is PROMISCUOUS and not FCS. In practice, the

Who says what the default filtering is for a monitor interface?

> filtering regarding the incoming frames will be exactly the same
> between FCS, PROMISCUOUS and SCAN, but in the PROMISCUOUS case we ask
> the PHY not to send ACKS (which is not the case of the FCS filtering
> level, acks can be automatically sent by the PHY, we don't want that).
>

Usually it's when we don't have a working address filter, then there
is no auto ackknowledge feature activated (I think this can be counted
as general rule for now). This is currently the case with the
set_promiscuousmode() driver ops.

> > You should also add a note on the filter level/modes which are
> > mandatory (means given by the spec) and put their level inside there?
> >
> > > >
> > > > >   receiving data) but of course if the PHY does not support
> > > > > this state (like hwsim) it should overwrite this value by
> > > > > setting the actual filtering level (none, in the hwsim case) so
> > > > > that the core knows what it receives.
> > > > >
> > > >
> > > > ok.
> > > >
> > > > > - I've replaced the specific "do not check the FCS" flag only
> > > > > used by hwsim by this filtering level, which gives all the
> > > > > information we need.
> > > > >
> > > >
> > > > ok.
> > > >
> > > > > - I've added a real promiscuous filtering mode which truly does
> > > > > not care about the content of the frame but only checks the FCS
> > > > > if not already done by the xceiver.
> > > > >
> > > >
> > > > not sure what a "real promiscuous filtering here is" people have
> > > > different understanding about it, but 802.15.4 has a definition
> > > > for it.
> > >
> > > Promiscuous, by the 802154 spec means: the FCS is good so the
> > > content of the received packet must means something, just forward
> > > it and let upper layers handle it.
> > >
> > > Until now there was no real promiscuous mode in the mac NODE rx
> > > path. Only monitors would get all the frames (including the ones
> > > with a wrong FCS), which is fine because it's a bit out of the
> > > spec, so I'm fine with this idea. But otherwise in the NODE/COORD
> > > rx path, the FCS should be checked even in promiscuous mode to
> > > correctly match the spec.
> >
> > If we parse the frame, the FCS should always be checked. The frame
> > should _never_ be parsed before it hits the monitor receive path.
>
> Yes.
>
> >
> > The wording "real promiscuous mode" is in my opinion still debatable,
> > however that's not the point here.
>
> I meant "like it is described in the spec".
>
> > > Until now, ieee802154_parse_frame_start() was always called in these
> > > path and this would validate the frame headers. I've added a more
> > > precise promiscuous mode in the rx patch which skips any additional
> > > checks. What happens however is that, if the transceiver disables
> > > FCS checks in promiscuous mode, then FCS is not checked at all and
> > > this is invalid. With my current implementation, the devices which
> > > do not check the FCS might be easily "fixed" by changing their PHY
> > > filtering level to "FILTERING_NONE" in the promiscuous callback.
> > >
> > > > You should consider that having monitors, frames with bad fcs
> > > > should not be filtered out by hardware. There it comes back what I
> > > > said before, the filtering level should be a parameter for start()
> > > > driver ops.
> > > >
> > > > > - I've also implemented in software filtering level 4 for most
> > > > > regular
> > > >
> > > > 3?
> > > >
> > > > >   data packets. Without changing the default PHY level
> > > > > mentioned in the first item above, this additional filtering
> > > > > will be skipped which ensures we keep the same behavior of most
> > > > > driver. In the case of hwsim however, these filters will become
> > > > > active if the MAC is not in promiscuous mode or in scan mode,
> > > > > which is actually what people should be expecting.
> > > > >
> > > >
> > > > To give feedback to that I need to see code. And please don't
> > > > send the whole feature stuff again, just this specific part of
> > > > it. Thanks.
> > >
> > > The entire filtering feature is split: there are the basis
> > > introduced before the scan, and then after the whole
> > > scan+association thing I've introduced additional filtering levels.
> > >
> >
> > No idea what that means.
>
> In my series, the first patches address the missing bits about
> filtering. Then there are patches about the scan. And finally there are
> two patches improving the filtering, which are not actually needed
> right now for the scan to work.
>

ok.

> > > > > Hopefully all this fits what you had in mind.
> > > > >
> > > > > I have one item left on my current todo list: improving a bit
> > > > > the userspace tool with a "monitor" command.
> > > > >
> > > > > Otherwise the remaining things to do are to discuss the locking
> > > > > design which might need to be changed to avoid lockdep issues
> > > > > and keep the rtnl locked eg. during a channel change. I still
> > > > > don't know how to do that, so it's likely that the right next
> > > > > version will not include any change in this area unless
> > > > > something pops up.
> > > >
> > > > I try to look at that on the weekend.
> > >
> > > I've had an idea yesterday night which seem to work, I think I can
> > > drop the two patches which you disliked regarding discarding the
> > > rtnl in the tx path and in hwsim:change_channel().
> >
> > I would like to bring the filtering level question at first upstream.
> > If you don't mind.
>
> The additional filtering which I've written has nothing to do with the
> scan, and more importantly it uses many new enums/helpers which are
> added along the way (by the scan series and the association series).
> Hence moving this filtering earlier in the series is a real pain and
> would anyway not bring anything really useful at this stage. All the
> important filtering changes are already available in the v2 series sent
> last week.
>
> Not mentioning, I would really like to move forward on the scan series
> as it's been in the air for quite some time.
>

I did not see the v2 until now. Sorry for that.

However I think there are missing bits here at the receive handling
side. Which are:

1. Do a stop_tx(), stop_rx(), start_rx(filtering_level) to go into
other filtering modes while ifup.

I don't want to see all filtering modes here, just what we currently
support with NONE (then with FCS check on software if necessary),
?THIRD/FOURTH? LEVEL filtering and that's it. What I don't want to see
is runtime changes of phy flags. To tell the receive path what to
filter and what's not.

2. set the pan coordinator bit for hw address filter. And there is a
TODO about setting pkt_type in mac802154 receive path which we should
take a look into. This bit should be addressed for coordinator support
even if there is the question about coordinator vs pan coordinator,
then the kernel needs a bit as coordinator iface type parameter to
know if it's a pan coordinator and not coordinator.

I think it makes total sense to split this work in transmit handling,
where we had no support at all to send something besides the usual
data path, and receive handling, where we have no way to change the
filtering level besides interface type and ifup time of an interface.
We are currently trying to make a receive path working in a way that
"the other ideas flying around which are good" can be introduced in
future.
If this is done, then take care about how to add the rest of it.

I will look into v2 the next few days.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-30  2:23                               ` Alexander Aring
@ 2022-08-31 15:39                                 ` Miquel Raynal
  2022-09-01  0:09                                   ` Miquel Raynal
  2022-09-02  2:09                                   ` Alexander Aring
  0 siblings, 2 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-08-31 15:39 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander & Stefan,

aahringo@redhat.com wrote on Mon, 29 Aug 2022 22:23:09 -0400:

I am currently testing my code with the ATUSB devices, the association
works, so it's a good news! However I am struggling to get the
association working for a simple reason: the crafted ACKs are
transmitted (the ATUSB in monitor mode sees it) but I get absolutely
nothing on the receiver side.

The logic is:

coord0                 coord1
association req ->
                <-     ack
                <-     association response
ack             ->

The first ack is sent by coord1 but coord0 never sees anything. In
practice coord0 has sent an association request and received a single
one-byte packet in return which I guess is the firmware saying "okay, Tx
has been performed". Shall I interpret this byte differently? Does it
mean that the ack has also been received? 

I could not find a documentation of the firmware interface, I went
through the wiki but I did not find something clear about what to
expect or "what the driver should do". But perhaps this will ring a
bell on your side?

[...]

> I did not see the v2 until now. Sorry for that.

Ah! Ok, no problem :)

> 
> However I think there are missing bits here at the receive handling
> side. Which are:
> 
> 1. Do a stop_tx(), stop_rx(), start_rx(filtering_level) to go into
> other filtering modes while ifup.

Who is supposed to change the filtering level?

For now there is only the promiscuous mode being applied and the user
has no knowledge about it, it's just something internal.

Changing how the promiscuous mode is applied (using a filtering level
instead of a "promiscuous on" boolean) would impact all the drivers
and for now we don't really need it.

> I don't want to see all filtering modes here, just what we currently
> support with NONE (then with FCS check on software if necessary),
> ?THIRD/FOURTH? LEVEL filtering and that's it. What I don't want to see
> is runtime changes of phy flags. To tell the receive path what to
> filter and what's not.

Runtime changes on a dedicated "filtering" PHY flag is what I've used
and it works okay for this situation, why don't you want that? It
avoids the need for (yet) another rework of the API with the drivers,
no?

> 2. set the pan coordinator bit for hw address filter. And there is a
> TODO about setting pkt_type in mac802154 receive path which we should
> take a look into. This bit should be addressed for coordinator support
> even if there is the question about coordinator vs pan coordinator,
> then the kernel needs a bit as coordinator iface type parameter to
> know if it's a pan coordinator and not coordinator.

This is not really something that we can "set". Either the device
had performed an association and it is a child device: it is not the
PAN coordinator, or it initiated the PAN and it is the PAN coordinator.
There are commands to change that later on but those are not supported.

The "PAN coordinator" information is being added in the association
series (which comes after the scan). I have handled the pkt_type you are
mentioning.

> I think it makes total sense to split this work in transmit handling,
> where we had no support at all to send something besides the usual
> data path, and receive handling, where we have no way to change the
> filtering level besides interface type and ifup time of an interface.
> We are currently trying to make a receive path working in a way that
> "the other ideas flying around which are good" can be introduced in
> future.
> If this is done, then take care about how to add the rest of it.
> 
> I will look into v2 the next few days.
> 
> - Alex
> 


Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-31 15:39                                 ` Miquel Raynal
@ 2022-09-01  0:09                                   ` Miquel Raynal
  2022-09-01 13:09                                     ` Miquel Raynal
  2022-09-02  2:23                                     ` Alexander Aring
  2022-09-02  2:09                                   ` Alexander Aring
  1 sibling, 2 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-09-01  0:09 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hello again,

miquel.raynal@bootlin.com wrote on Wed, 31 Aug 2022 17:39:03 +0200:

> Hi Alexander & Stefan,
> 
> aahringo@redhat.com wrote on Mon, 29 Aug 2022 22:23:09 -0400:
> 
> I am currently testing my code with the ATUSB devices, the association
> works, so it's a good news! However I am struggling to get the
> association working for a simple reason: the crafted ACKs are
> transmitted (the ATUSB in monitor mode sees it) but I get absolutely
> nothing on the receiver side.
> 
> The logic is:
> 
> coord0                 coord1
> association req ->
>                 <-     ack
>                 <-     association response
> ack             ->
> 
> The first ack is sent by coord1 but coord0 never sees anything. In
> practice coord0 has sent an association request and received a single
> one-byte packet in return which I guess is the firmware saying "okay, Tx
> has been performed". Shall I interpret this byte differently? Does it
> mean that the ack has also been received?

I think I now have a clearer understanding on how the devices behave.

I turned the devices into promiscuous mode and could observe that some
frames were considered wrong. Indeed, it looks like the PHYs add the
FCS themselves, while the spec says that the FCS should be provided to
the PHY. Anyway, I dropped the FCS calculations from the different MLME
frames forged and it helped a lot.

I also kind of "discovered" the concept of hardware address filtering
on atusb which makes me realize that maybe we were not talking about
the same "filtering" until now.

Associations and disassociations now work properly, I'm glad I fixed
"everything". I still need to figure out if using the promiscuous mode
everywhere is really useful or not (maybe the hardware filters were
disabled in this mode and it made it work). However, using the
promiscuous mode was the only way I had to receive acknowledgements,
otherwise they were filtered out by the hardware (the monitor was
showing that the ack frames were actually being sent).

Finally, changing the channel was also a piece of the puzzle, because I
think some of my smart light bulbs tried to say hello and it kind of
disturbed me :)

> I could not find a documentation of the firmware interface, I went
> through the wiki but I did not find something clear about what to
> expect or "what the driver should do". But perhaps this will ring a
> bell on your side?
> 
> [...]
> 
> > I did not see the v2 until now. Sorry for that.  
> 
> Ah! Ok, no problem :)
> 
> > 
> > However I think there are missing bits here at the receive handling
> > side. Which are:
> > 
> > 1. Do a stop_tx(), stop_rx(), start_rx(filtering_level) to go into
> > other filtering modes while ifup.  
> 
> Who is supposed to change the filtering level?
> 
> For now there is only the promiscuous mode being applied and the user
> has no knowledge about it, it's just something internal.
> 
> Changing how the promiscuous mode is applied (using a filtering level
> instead of a "promiscuous on" boolean) would impact all the drivers
> and for now we don't really need it.
> 
> > I don't want to see all filtering modes here, just what we currently
> > support with NONE (then with FCS check on software if necessary),
> > ?THIRD/FOURTH? LEVEL filtering and that's it. What I don't want to see
> > is runtime changes of phy flags. To tell the receive path what to
> > filter and what's not.  
> 
> Runtime changes on a dedicated "filtering" PHY flag is what I've used
> and it works okay for this situation, why don't you want that? It
> avoids the need for (yet) another rework of the API with the drivers,
> no?
> 
> > 2. set the pan coordinator bit for hw address filter. And there is a
> > TODO about setting pkt_type in mac802154 receive path which we should
> > take a look into. This bit should be addressed for coordinator support
> > even if there is the question about coordinator vs pan coordinator,
> > then the kernel needs a bit as coordinator iface type parameter to
> > know if it's a pan coordinator and not coordinator.  
> 
> This is not really something that we can "set". Either the device
> had performed an association and it is a child device: it is not the
> PAN coordinator, or it initiated the PAN and it is the PAN coordinator.
> There are commands to change that later on but those are not supported.
> 
> The "PAN coordinator" information is being added in the association
> series (which comes after the scan). I have handled the pkt_type you are
> mentioning.
> 
> > I think it makes total sense to split this work in transmit handling,
> > where we had no support at all to send something besides the usual
> > data path, and receive handling, where we have no way to change the
> > filtering level besides interface type and ifup time of an interface.
> > We are currently trying to make a receive path working in a way that
> > "the other ideas flying around which are good" can be introduced in
> > future.
> > If this is done, then take care about how to add the rest of it.
> > 
> > I will look into v2 the next few days.

If possible, I would really like to understand what you expect in terms
of filtering. Maybe as well a short snippet of code showing what kind
of interface you have in mind. Are we talking about a rework of the
promiscuous callback? Are we talking about the hardware filters? What
are the inputs and outputs for these callbacks? What do we expect from
the drivers in terms of advertising? I will be glad to make the
relevant changes once I understand what is needed because on this topic
I have a clear lack of experience, so I will try to judge what is
reachable based on your inputs.

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-09-01  0:09                                   ` Miquel Raynal
@ 2022-09-01 13:09                                     ` Miquel Raynal
  2022-09-02  2:38                                       ` Alexander Aring
  2022-09-02  2:23                                     ` Alexander Aring
  1 sibling, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-09-01 13:09 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hello,

miquel.raynal@bootlin.com wrote on Thu, 1 Sep 2022 02:09:18 +0200:

> Hello again,
> 
> miquel.raynal@bootlin.com wrote on Wed, 31 Aug 2022 17:39:03 +0200:
> 
> > Hi Alexander & Stefan,
> > 
> > aahringo@redhat.com wrote on Mon, 29 Aug 2022 22:23:09 -0400:
> > 
> > I am currently testing my code with the ATUSB devices, the association
> > works, so it's a good news! However I am struggling to get the
> > association working for a simple reason: the crafted ACKs are
> > transmitted (the ATUSB in monitor mode sees it) but I get absolutely
> > nothing on the receiver side.
> > 
> > The logic is:
> > 
> > coord0                 coord1
> > association req ->
> >                 <-     ack
> >                 <-     association response
> > ack             ->
> > 
> > The first ack is sent by coord1 but coord0 never sees anything. In
> > practice coord0 has sent an association request and received a single
> > one-byte packet in return which I guess is the firmware saying "okay, Tx
> > has been performed". Shall I interpret this byte differently? Does it
> > mean that the ack has also been received?  
> 
> I think I now have a clearer understanding on how the devices behave.
> 
> I turned the devices into promiscuous mode and could observe that some
> frames were considered wrong. Indeed, it looks like the PHYs add the
> FCS themselves, while the spec says that the FCS should be provided to
> the PHY. Anyway, I dropped the FCS calculations from the different MLME
> frames forged and it helped a lot.
> 
> I also kind of "discovered" the concept of hardware address filtering
> on atusb which makes me realize that maybe we were not talking about
> the same "filtering" until now.
> 
> Associations and disassociations now work properly, I'm glad I fixed
> "everything". I still need to figure out if using the promiscuous mode
> everywhere is really useful or not (maybe the hardware filters were
> disabled in this mode and it made it work). However, using the
> promiscuous mode was the only way I had to receive acknowledgements,
> otherwise they were filtered out by the hardware (the monitor was
> showing that the ack frames were actually being sent).
> 
> Finally, changing the channel was also a piece of the puzzle, because I
> think some of my smart light bulbs tried to say hello and it kind of
> disturbed me :)

I tried to scan my ATUSB devices from a Zephyr based Arduino Nano
BLE but for now it does not work, the ATUSB devices receive the scan
requests from Zephyr and send their beacons, the ATUSB monitor shows
the beacons on Wireshark but the ieee80154_recv() callback is never
triggered on Zephyr side. I am new to this OS so if you have any idea
or debugging tips, I would be glad to hear them.

> > I could not find a documentation of the firmware interface, I went
> > through the wiki but I did not find something clear about what to
> > expect or "what the driver should do". But perhaps this will ring a
> > bell on your side?
> > 
> > [...]
> >   
> > > I did not see the v2 until now. Sorry for that.    
> > 
> > Ah! Ok, no problem :)
> >   
> > > 
> > > However I think there are missing bits here at the receive handling
> > > side. Which are:
> > > 
> > > 1. Do a stop_tx(), stop_rx(), start_rx(filtering_level) to go into
> > > other filtering modes while ifup.    
> > 
> > Who is supposed to change the filtering level?
> > 
> > For now there is only the promiscuous mode being applied and the user
> > has no knowledge about it, it's just something internal.
> > 
> > Changing how the promiscuous mode is applied (using a filtering level
> > instead of a "promiscuous on" boolean) would impact all the drivers
> > and for now we don't really need it.
> >   
> > > I don't want to see all filtering modes here, just what we currently
> > > support with NONE (then with FCS check on software if necessary),
> > > ?THIRD/FOURTH? LEVEL filtering and that's it. What I don't want to see
> > > is runtime changes of phy flags. To tell the receive path what to
> > > filter and what's not.    
> > 
> > Runtime changes on a dedicated "filtering" PHY flag is what I've used
> > and it works okay for this situation, why don't you want that? It
> > avoids the need for (yet) another rework of the API with the drivers,
> > no?
> >   
> > > 2. set the pan coordinator bit for hw address filter. And there is a
> > > TODO about setting pkt_type in mac802154 receive path which we should
> > > take a look into. This bit should be addressed for coordinator support
> > > even if there is the question about coordinator vs pan coordinator,
> > > then the kernel needs a bit as coordinator iface type parameter to
> > > know if it's a pan coordinator and not coordinator.    
> > 
> > This is not really something that we can "set". Either the device
> > had performed an association and it is a child device: it is not the
> > PAN coordinator, or it initiated the PAN and it is the PAN coordinator.
> > There are commands to change that later on but those are not supported.
> > 
> > The "PAN coordinator" information is being added in the association
> > series (which comes after the scan). I have handled the pkt_type you are
> > mentioning.
> >   
> > > I think it makes total sense to split this work in transmit handling,
> > > where we had no support at all to send something besides the usual
> > > data path, and receive handling, where we have no way to change the
> > > filtering level besides interface type and ifup time of an interface.
> > > We are currently trying to make a receive path working in a way that
> > > "the other ideas flying around which are good" can be introduced in
> > > future.
> > > If this is done, then take care about how to add the rest of it.
> > > 
> > > I will look into v2 the next few days.  
> 
> If possible, I would really like to understand what you expect in terms
> of filtering. Maybe as well a short snippet of code showing what kind
> of interface you have in mind. Are we talking about a rework of the
> promiscuous callback? Are we talking about the hardware filters? What
> are the inputs and outputs for these callbacks? What do we expect from
> the drivers in terms of advertising? I will be glad to make the
> relevant changes once I understand what is needed because on this topic
> I have a clear lack of experience, so I will try to judge what is
> reachable based on your inputs.

Also, can you please clarify when are we talking about software and
when about hardware filters.

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-08-31 15:39                                 ` Miquel Raynal
  2022-09-01  0:09                                   ` Miquel Raynal
@ 2022-09-02  2:09                                   ` Alexander Aring
  1 sibling, 0 replies; 84+ messages in thread
From: Alexander Aring @ 2022-09-02  2:09 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Wed, Aug 31, 2022 at 11:39 AM Miquel Raynal
<miquel.raynal@bootlin.com> wrote:
>
> Hi Alexander & Stefan,
>
> aahringo@redhat.com wrote on Mon, 29 Aug 2022 22:23:09 -0400:
>
> I am currently testing my code with the ATUSB devices, the association
> works, so it's a good news! However I am struggling to get the
> association working for a simple reason: the crafted ACKs are
> transmitted (the ATUSB in monitor mode sees it) but I get absolutely

What is a crafted ACK here?

> nothing on the receiver side.
>
> The logic is:
>
> coord0                 coord1
> association req ->
>                 <-     ack
>                 <-     association response
> ack             ->
>
> The first ack is sent by coord1 but coord0 never sees anything. In
> practice coord0 has sent an association request and received a single
> one-byte packet in return which I guess is the firmware saying "okay, Tx
> has been performed". Shall I interpret this byte differently? Does it
> mean that the ack has also been received?
>
> I could not find a documentation of the firmware interface, I went
> through the wiki but I did not find something clear about what to
> expect or "what the driver should do". But perhaps this will ring a
> bell on your side?
>
> [...]
>
> > I did not see the v2 until now. Sorry for that.
>
> Ah! Ok, no problem :)
>
> >
> > However I think there are missing bits here at the receive handling
> > side. Which are:
> >
> > 1. Do a stop_tx(), stop_rx(), start_rx(filtering_level) to go into
> > other filtering modes while ifup.
>
> Who is supposed to change the filtering level?
>

depending on what mac802154 is doing, for scan it's required to switch
the filter level to promiscuous?

> For now there is only the promiscuous mode being applied and the user
> has no knowledge about it, it's just something internal.
>

Okay, sounds good.

> Changing how the promiscuous mode is applied (using a filtering level
> instead of a "promiscuous on" boolean) would impact all the drivers
> and for now we don't really need it.
>

no, it does not. Okay, you can hide the promiscuous mode driver
callback from start()... but yes the goal would be to remove the
promiscuous mode op in future.

> > I don't want to see all filtering modes here, just what we currently
> > support with NONE (then with FCS check on software if necessary),
> > ?THIRD/FOURTH? LEVEL filtering and that's it. What I don't want to see
> > is runtime changes of phy flags. To tell the receive path what to
> > filter and what's not.
>
> Runtime changes on a dedicated "filtering" PHY flag is what I've used
> and it works okay for this situation, why don't you want that? It
> avoids the need for (yet) another rework of the API with the drivers,
> no?
>

I am not sure what exactly here is "dedicated "filtering" PHY flag" if
it's the hwflags it was never made to be changed during runtime.

I also don't know what "yet another rework of the API" means here,
there is a current behaviour which we can assume and only hwsim is a
little bit out of range which should overwrite the "default".

> > 2. set the pan coordinator bit for hw address filter. And there is a
> > TODO about setting pkt_type in mac802154 receive path which we should
> > take a look into. This bit should be addressed for coordinator support
> > even if there is the question about coordinator vs pan coordinator,
> > then the kernel needs a bit as coordinator iface type parameter to
> > know if it's a pan coordinator and not coordinator.
>
> This is not really something that we can "set". Either the device
> had performed an association and it is a child device: it is not the
> PAN coordinator, or it initiated the PAN and it is the PAN coordinator.
> There are commands to change that later on but those are not supported.
>
> The "PAN coordinator" information is being added in the association
> series (which comes after the scan). I have handled the pkt_type you are
> mentioning.
>

okay.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-09-01  0:09                                   ` Miquel Raynal
  2022-09-01 13:09                                     ` Miquel Raynal
@ 2022-09-02  2:23                                     ` Alexander Aring
  2022-09-02  2:39                                       ` Alexander Aring
  1 sibling, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-09-02  2:23 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Wed, Aug 31, 2022 at 8:09 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> Hello again,
>
> miquel.raynal@bootlin.com wrote on Wed, 31 Aug 2022 17:39:03 +0200:
>
> > Hi Alexander & Stefan,
> >
> > aahringo@redhat.com wrote on Mon, 29 Aug 2022 22:23:09 -0400:
> >
> > I am currently testing my code with the ATUSB devices, the association
> > works, so it's a good news! However I am struggling to get the
> > association working for a simple reason: the crafted ACKs are
> > transmitted (the ATUSB in monitor mode sees it) but I get absolutely
> > nothing on the receiver side.
> >
> > The logic is:
> >
> > coord0                 coord1
> > association req ->
> >                 <-     ack
> >                 <-     association response
> > ack             ->
> >
> > The first ack is sent by coord1 but coord0 never sees anything. In
> > practice coord0 has sent an association request and received a single
> > one-byte packet in return which I guess is the firmware saying "okay, Tx
> > has been performed". Shall I interpret this byte differently? Does it
> > mean that the ack has also been received?
>
> I think I now have a clearer understanding on how the devices behave.
>
> I turned the devices into promiscuous mode and could observe that some
> frames were considered wrong. Indeed, it looks like the PHYs add the
> FCS themselves, while the spec says that the FCS should be provided to
> the PHY. Anyway, I dropped the FCS calculations from the different MLME
> frames forged and it helped a lot.
>

This is currently the case because monitor interfaces and AF_PACKET
will not have the FCS in the payload. As you already figured out you
can't refer 802.15.4 promiscuous mode to mac802154 promiscuous mode,
it was a historically growing term as people wanted to have a sniffer
device and used a promiscuous term from a datasheet (my guess).
Vendors has a different meaning of promiscuous mode as the one from
802.15.4. IFF_PROMISC should be mapped to non-filtered mode which is
more equal to a sniffer device. However we need to find solutions
which fulfill everybody.

> I also kind of "discovered" the concept of hardware address filtering
> on atusb which makes me realize that maybe we were not talking about
> the same "filtering" until now.
>
> Associations and disassociations now work properly, I'm glad I fixed
> "everything". I still need to figure out if using the promiscuous mode
> everywhere is really useful or not (maybe the hardware filters were
> disabled in this mode and it made it work). However, using the
> promiscuous mode was the only way I had to receive acknowledgements,
> otherwise they were filtered out by the hardware (the monitor was
> showing that the ack frames were actually being sent).
>

This is correct, the most hardware will turn off automatic
ackknowledge handling if address filtering is off (I am sure I said
that before). We cannot handle acks on mac802154 if they are time
critical.

> Finally, changing the channel was also a piece of the puzzle, because I
> think some of my smart light bulbs tried to say hello and it kind of
> disturbed me :)
>
> > I could not find a documentation of the firmware interface, I went
> > through the wiki but I did not find something clear about what to
> > expect or "what the driver should do". But perhaps this will ring a
> > bell on your side?
> >
> > [...]
> >
> > > I did not see the v2 until now. Sorry for that.
> >
> > Ah! Ok, no problem :)
> >
> > >
> > > However I think there are missing bits here at the receive handling
> > > side. Which are:
> > >
> > > 1. Do a stop_tx(), stop_rx(), start_rx(filtering_level) to go into
> > > other filtering modes while ifup.
> >
> > Who is supposed to change the filtering level?
> >
> > For now there is only the promiscuous mode being applied and the user
> > has no knowledge about it, it's just something internal.
> >
> > Changing how the promiscuous mode is applied (using a filtering level
> > instead of a "promiscuous on" boolean) would impact all the drivers
> > and for now we don't really need it.
> >
> > > I don't want to see all filtering modes here, just what we currently
> > > support with NONE (then with FCS check on software if necessary),
> > > ?THIRD/FOURTH? LEVEL filtering and that's it. What I don't want to see
> > > is runtime changes of phy flags. To tell the receive path what to
> > > filter and what's not.
> >
> > Runtime changes on a dedicated "filtering" PHY flag is what I've used
> > and it works okay for this situation, why don't you want that? It
> > avoids the need for (yet) another rework of the API with the drivers,
> > no?
> >
> > > 2. set the pan coordinator bit for hw address filter. And there is a
> > > TODO about setting pkt_type in mac802154 receive path which we should
> > > take a look into. This bit should be addressed for coordinator support
> > > even if there is the question about coordinator vs pan coordinator,
> > > then the kernel needs a bit as coordinator iface type parameter to
> > > know if it's a pan coordinator and not coordinator.
> >
> > This is not really something that we can "set". Either the device
> > had performed an association and it is a child device: it is not the
> > PAN coordinator, or it initiated the PAN and it is the PAN coordinator.
> > There are commands to change that later on but those are not supported.
> >
> > The "PAN coordinator" information is being added in the association
> > series (which comes after the scan). I have handled the pkt_type you are
> > mentioning.
> >
> > > I think it makes total sense to split this work in transmit handling,
> > > where we had no support at all to send something besides the usual
> > > data path, and receive handling, where we have no way to change the
> > > filtering level besides interface type and ifup time of an interface.
> > > We are currently trying to make a receive path working in a way that
> > > "the other ideas flying around which are good" can be introduced in
> > > future.
> > > If this is done, then take care about how to add the rest of it.
> > >
> > > I will look into v2 the next few days.
>
> If possible, I would really like to understand what you expect in terms
> of filtering. Maybe as well a short snippet of code showing what kind
> of interface you have in mind. Are we talking about a rework of the
> promiscuous callback? Are we talking about the hardware filters? What

I try to do that over the weekend. Monday is a holiday here.

> are the inputs and outputs for these callbacks? What do we expect from
> the drivers in terms of advertising? I will be glad to make the
> relevant changes once I understand what is needed because on this topic
> I have a clear lack of experience, so I will try to judge what is
> reachable based on your inputs.

ok.

Thanks.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-09-01 13:09                                     ` Miquel Raynal
@ 2022-09-02  2:38                                       ` Alexander Aring
  2022-09-03  0:08                                         ` Miquel Raynal
  0 siblings, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-09-02  2:38 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Thu, Sep 1, 2022 at 9:09 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> Hello,
>
> miquel.raynal@bootlin.com wrote on Thu, 1 Sep 2022 02:09:18 +0200:
>
> > Hello again,
> >
> > miquel.raynal@bootlin.com wrote on Wed, 31 Aug 2022 17:39:03 +0200:
> >
> > > Hi Alexander & Stefan,
> > >
> > > aahringo@redhat.com wrote on Mon, 29 Aug 2022 22:23:09 -0400:
> > >
> > > I am currently testing my code with the ATUSB devices, the association
> > > works, so it's a good news! However I am struggling to get the
> > > association working for a simple reason: the crafted ACKs are
> > > transmitted (the ATUSB in monitor mode sees it) but I get absolutely
> > > nothing on the receiver side.
> > >
> > > The logic is:
> > >
> > > coord0                 coord1
> > > association req ->
> > >                 <-     ack
> > >                 <-     association response
> > > ack             ->
> > >
> > > The first ack is sent by coord1 but coord0 never sees anything. In
> > > practice coord0 has sent an association request and received a single
> > > one-byte packet in return which I guess is the firmware saying "okay, Tx
> > > has been performed". Shall I interpret this byte differently? Does it
> > > mean that the ack has also been received?
> >
> > I think I now have a clearer understanding on how the devices behave.
> >
> > I turned the devices into promiscuous mode and could observe that some
> > frames were considered wrong. Indeed, it looks like the PHYs add the
> > FCS themselves, while the spec says that the FCS should be provided to
> > the PHY. Anyway, I dropped the FCS calculations from the different MLME
> > frames forged and it helped a lot.
> >
> > I also kind of "discovered" the concept of hardware address filtering
> > on atusb which makes me realize that maybe we were not talking about
> > the same "filtering" until now.
> >
> > Associations and disassociations now work properly, I'm glad I fixed
> > "everything". I still need to figure out if using the promiscuous mode
> > everywhere is really useful or not (maybe the hardware filters were
> > disabled in this mode and it made it work). However, using the
> > promiscuous mode was the only way I had to receive acknowledgements,
> > otherwise they were filtered out by the hardware (the monitor was
> > showing that the ack frames were actually being sent).
> >
> > Finally, changing the channel was also a piece of the puzzle, because I
> > think some of my smart light bulbs tried to say hello and it kind of
> > disturbed me :)
>
> I tried to scan my ATUSB devices from a Zephyr based Arduino Nano
> BLE but for now it does not work, the ATUSB devices receive the scan
> requests from Zephyr and send their beacons, the ATUSB monitor shows
> the beacons on Wireshark but the ieee80154_recv() callback is never
> triggered on Zephyr side. I am new to this OS so if you have any idea
> or debugging tips, I would be glad to hear them.
>
> > > I could not find a documentation of the firmware interface, I went
> > > through the wiki but I did not find something clear about what to
> > > expect or "what the driver should do". But perhaps this will ring a
> > > bell on your side?
> > >
> > > [...]
> > >
> > > > I did not see the v2 until now. Sorry for that.
> > >
> > > Ah! Ok, no problem :)
> > >
> > > >
> > > > However I think there are missing bits here at the receive handling
> > > > side. Which are:
> > > >
> > > > 1. Do a stop_tx(), stop_rx(), start_rx(filtering_level) to go into
> > > > other filtering modes while ifup.
> > >
> > > Who is supposed to change the filtering level?
> > >
> > > For now there is only the promiscuous mode being applied and the user
> > > has no knowledge about it, it's just something internal.
> > >
> > > Changing how the promiscuous mode is applied (using a filtering level
> > > instead of a "promiscuous on" boolean) would impact all the drivers
> > > and for now we don't really need it.
> > >
> > > > I don't want to see all filtering modes here, just what we currently
> > > > support with NONE (then with FCS check on software if necessary),
> > > > ?THIRD/FOURTH? LEVEL filtering and that's it. What I don't want to see
> > > > is runtime changes of phy flags. To tell the receive path what to
> > > > filter and what's not.
> > >
> > > Runtime changes on a dedicated "filtering" PHY flag is what I've used
> > > and it works okay for this situation, why don't you want that? It
> > > avoids the need for (yet) another rework of the API with the drivers,
> > > no?
> > >
> > > > 2. set the pan coordinator bit for hw address filter. And there is a
> > > > TODO about setting pkt_type in mac802154 receive path which we should
> > > > take a look into. This bit should be addressed for coordinator support
> > > > even if there is the question about coordinator vs pan coordinator,
> > > > then the kernel needs a bit as coordinator iface type parameter to
> > > > know if it's a pan coordinator and not coordinator.
> > >
> > > This is not really something that we can "set". Either the device
> > > had performed an association and it is a child device: it is not the
> > > PAN coordinator, or it initiated the PAN and it is the PAN coordinator.
> > > There are commands to change that later on but those are not supported.
> > >
> > > The "PAN coordinator" information is being added in the association
> > > series (which comes after the scan). I have handled the pkt_type you are
> > > mentioning.
> > >
> > > > I think it makes total sense to split this work in transmit handling,
> > > > where we had no support at all to send something besides the usual
> > > > data path, and receive handling, where we have no way to change the
> > > > filtering level besides interface type and ifup time of an interface.
> > > > We are currently trying to make a receive path working in a way that
> > > > "the other ideas flying around which are good" can be introduced in
> > > > future.
> > > > If this is done, then take care about how to add the rest of it.
> > > >
> > > > I will look into v2 the next few days.
> >
> > If possible, I would really like to understand what you expect in terms
> > of filtering. Maybe as well a short snippet of code showing what kind
> > of interface you have in mind. Are we talking about a rework of the
> > promiscuous callback? Are we talking about the hardware filters? What
> > are the inputs and outputs for these callbacks? What do we expect from
> > the drivers in terms of advertising? I will be glad to make the
> > relevant changes once I understand what is needed because on this topic
> > I have a clear lack of experience, so I will try to judge what is
> > reachable based on your inputs.
>

I am sorry, I never looked into Zephyr for reasons... Do they not have
something like /proc/interrupts look if you see a counter for your
802.15.4 transceiver?

> Also, can you please clarify when are we talking about software and
> when about hardware filters.
>

Hardware filter is currently e.g. promiscuous mode on or off setting.
Software filtering is depending which receive path the frame is going
and which hardware filter is present which then acts like actually
with hardware filtering.
I am not sure if this answers this question?

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-09-02  2:23                                     ` Alexander Aring
@ 2022-09-02  2:39                                       ` Alexander Aring
  0 siblings, 0 replies; 84+ messages in thread
From: Alexander Aring @ 2022-09-02  2:39 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Thu, Sep 1, 2022 at 10:23 PM Alexander Aring <aahringo@redhat.com> wrote:
>
> Hi,
>
> On Wed, Aug 31, 2022 at 8:09 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> >
> > Hello again,
> >
> > miquel.raynal@bootlin.com wrote on Wed, 31 Aug 2022 17:39:03 +0200:
> >
> > > Hi Alexander & Stefan,
> > >
> > > aahringo@redhat.com wrote on Mon, 29 Aug 2022 22:23:09 -0400:
> > >
> > > I am currently testing my code with the ATUSB devices, the association
> > > works, so it's a good news! However I am struggling to get the
> > > association working for a simple reason: the crafted ACKs are
> > > transmitted (the ATUSB in monitor mode sees it) but I get absolutely
> > > nothing on the receiver side.
> > >
> > > The logic is:
> > >
> > > coord0                 coord1
> > > association req ->
> > >                 <-     ack
> > >                 <-     association response
> > > ack             ->
> > >
> > > The first ack is sent by coord1 but coord0 never sees anything. In
> > > practice coord0 has sent an association request and received a single
> > > one-byte packet in return which I guess is the firmware saying "okay, Tx
> > > has been performed". Shall I interpret this byte differently? Does it
> > > mean that the ack has also been received?
> >
> > I think I now have a clearer understanding on how the devices behave.
> >
> > I turned the devices into promiscuous mode and could observe that some
> > frames were considered wrong. Indeed, it looks like the PHYs add the
> > FCS themselves, while the spec says that the FCS should be provided to
> > the PHY. Anyway, I dropped the FCS calculations from the different MLME
> > frames forged and it helped a lot.
> >
>
> This is currently the case because monitor interfaces and AF_PACKET
> will not have the FCS in the payload. As you already figured out you
> can't refer 802.15.4 promiscuous mode to mac802154 promiscuous mode,
> it was a historically growing term as people wanted to have a sniffer
> device and used a promiscuous term from a datasheet (my guess).
> Vendors has a different meaning of promiscuous mode as the one from
> 802.15.4. IFF_PROMISC should be mapped to non-filtered mode which is
> more equal to a sniffer device. However we need to find solutions
> which fulfill everybody.
>
> > I also kind of "discovered" the concept of hardware address filtering
> > on atusb which makes me realize that maybe we were not talking about
> > the same "filtering" until now.
> >
> > Associations and disassociations now work properly, I'm glad I fixed
> > "everything". I still need to figure out if using the promiscuous mode
> > everywhere is really useful or not (maybe the hardware filters were
> > disabled in this mode and it made it work). However, using the
> > promiscuous mode was the only way I had to receive acknowledgements,
> > otherwise they were filtered out by the hardware (the monitor was
> > showing that the ack frames were actually being sent).
> >
>
> This is correct, the most hardware will turn off automatic
> ackknowledge handling if address filtering is off (I am sure I said
> that before). We cannot handle acks on mac802154 if they are time
> critical.
>

If this is required we should discuss this topic...

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-09-02  2:38                                       ` Alexander Aring
@ 2022-09-03  0:08                                         ` Miquel Raynal
  2022-09-03 14:20                                           ` Alexander Aring
  0 siblings, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-09-03  0:08 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Thu, 1 Sep 2022 22:38:12 -0400:

> Hi,
> 
> On Thu, Sep 1, 2022 at 9:09 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> >
> > Hello,
> >
> > miquel.raynal@bootlin.com wrote on Thu, 1 Sep 2022 02:09:18 +0200:
> >  
> > > Hello again,
> > >
> > > miquel.raynal@bootlin.com wrote on Wed, 31 Aug 2022 17:39:03 +0200:
> > >  
> > > > Hi Alexander & Stefan,
> > > >
> > > > aahringo@redhat.com wrote on Mon, 29 Aug 2022 22:23:09 -0400:
> > > >
> > > > I am currently testing my code with the ATUSB devices, the association
> > > > works, so it's a good news! However I am struggling to get the
> > > > association working for a simple reason: the crafted ACKs are
> > > > transmitted (the ATUSB in monitor mode sees it) but I get absolutely
> > > > nothing on the receiver side.
> > > >
> > > > The logic is:
> > > >
> > > > coord0                 coord1
> > > > association req ->
> > > >                 <-     ack
> > > >                 <-     association response
> > > > ack             ->
> > > >
> > > > The first ack is sent by coord1 but coord0 never sees anything. In
> > > > practice coord0 has sent an association request and received a single
> > > > one-byte packet in return which I guess is the firmware saying "okay, Tx
> > > > has been performed". Shall I interpret this byte differently? Does it
> > > > mean that the ack has also been received?  
> > >
> > > I think I now have a clearer understanding on how the devices behave.
> > >
> > > I turned the devices into promiscuous mode and could observe that some
> > > frames were considered wrong. Indeed, it looks like the PHYs add the
> > > FCS themselves, while the spec says that the FCS should be provided to
> > > the PHY. Anyway, I dropped the FCS calculations from the different MLME
> > > frames forged and it helped a lot.
> > >
> > > I also kind of "discovered" the concept of hardware address filtering
> > > on atusb which makes me realize that maybe we were not talking about
> > > the same "filtering" until now.
> > >
> > > Associations and disassociations now work properly, I'm glad I fixed
> > > "everything". I still need to figure out if using the promiscuous mode
> > > everywhere is really useful or not (maybe the hardware filters were
> > > disabled in this mode and it made it work). However, using the
> > > promiscuous mode was the only way I had to receive acknowledgements,
> > > otherwise they were filtered out by the hardware (the monitor was
> > > showing that the ack frames were actually being sent).
> > >
> > > Finally, changing the channel was also a piece of the puzzle, because I
> > > think some of my smart light bulbs tried to say hello and it kind of
> > > disturbed me :)  
> >
> > I tried to scan my ATUSB devices from a Zephyr based Arduino Nano
> > BLE but for now it does not work, the ATUSB devices receive the scan
> > requests from Zephyr and send their beacons, the ATUSB monitor shows
> > the beacons on Wireshark but the ieee80154_recv() callback is never
> > triggered on Zephyr side. I am new to this OS so if you have any idea
> > or debugging tips, I would be glad to hear them.
> >  
> > > > I could not find a documentation of the firmware interface, I went
> > > > through the wiki but I did not find something clear about what to
> > > > expect or "what the driver should do". But perhaps this will ring a
> > > > bell on your side?
> > > >
> > > > [...]
> > > >  
> > > > > I did not see the v2 until now. Sorry for that.  
> > > >
> > > > Ah! Ok, no problem :)
> > > >  
> > > > >
> > > > > However I think there are missing bits here at the receive handling
> > > > > side. Which are:
> > > > >
> > > > > 1. Do a stop_tx(), stop_rx(), start_rx(filtering_level) to go into
> > > > > other filtering modes while ifup.  
> > > >
> > > > Who is supposed to change the filtering level?
> > > >
> > > > For now there is only the promiscuous mode being applied and the user
> > > > has no knowledge about it, it's just something internal.
> > > >
> > > > Changing how the promiscuous mode is applied (using a filtering level
> > > > instead of a "promiscuous on" boolean) would impact all the drivers
> > > > and for now we don't really need it.
> > > >  
> > > > > I don't want to see all filtering modes here, just what we currently
> > > > > support with NONE (then with FCS check on software if necessary),
> > > > > ?THIRD/FOURTH? LEVEL filtering and that's it. What I don't want to see
> > > > > is runtime changes of phy flags. To tell the receive path what to
> > > > > filter and what's not.  
> > > >
> > > > Runtime changes on a dedicated "filtering" PHY flag is what I've used
> > > > and it works okay for this situation, why don't you want that? It
> > > > avoids the need for (yet) another rework of the API with the drivers,
> > > > no?
> > > >  
> > > > > 2. set the pan coordinator bit for hw address filter. And there is a
> > > > > TODO about setting pkt_type in mac802154 receive path which we should
> > > > > take a look into. This bit should be addressed for coordinator support
> > > > > even if there is the question about coordinator vs pan coordinator,
> > > > > then the kernel needs a bit as coordinator iface type parameter to
> > > > > know if it's a pan coordinator and not coordinator.  
> > > >
> > > > This is not really something that we can "set". Either the device
> > > > had performed an association and it is a child device: it is not the
> > > > PAN coordinator, or it initiated the PAN and it is the PAN coordinator.
> > > > There are commands to change that later on but those are not supported.
> > > >
> > > > The "PAN coordinator" information is being added in the association
> > > > series (which comes after the scan). I have handled the pkt_type you are
> > > > mentioning.
> > > >  
> > > > > I think it makes total sense to split this work in transmit handling,
> > > > > where we had no support at all to send something besides the usual
> > > > > data path, and receive handling, where we have no way to change the
> > > > > filtering level besides interface type and ifup time of an interface.
> > > > > We are currently trying to make a receive path working in a way that
> > > > > "the other ideas flying around which are good" can be introduced in
> > > > > future.
> > > > > If this is done, then take care about how to add the rest of it.
> > > > >
> > > > > I will look into v2 the next few days.  
> > >
> > > If possible, I would really like to understand what you expect in terms
> > > of filtering. Maybe as well a short snippet of code showing what kind
> > > of interface you have in mind. Are we talking about a rework of the
> > > promiscuous callback? Are we talking about the hardware filters? What
> > > are the inputs and outputs for these callbacks? What do we expect from
> > > the drivers in terms of advertising? I will be glad to make the
> > > relevant changes once I understand what is needed because on this topic
> > > I have a clear lack of experience, so I will try to judge what is
> > > reachable based on your inputs.  
> >  
> 
> I am sorry, I never looked into Zephyr for reasons... Do they not have
> something like /proc/interrupts look if you see a counter for your
> 802.15.4 transceiver?
> 
> > Also, can you please clarify when are we talking about software and
> > when about hardware filters.
> >  
> 
> Hardware filter is currently e.g. promiscuous mode on or off setting.
> Software filtering is depending which receive path the frame is going
> and which hardware filter is present which then acts like actually
> with hardware filtering.
> I am not sure if this answers this question?

I think my understand gets clearer now that I've digged into Zephyr's
ieee802154 layer and in the at86rf230 datasheet.

I will answer the previous e-mail but just for not I wanted to add that
I managed to get Zephyr working, I had to mess around in the code a
little bit and actually I discovered a net command which is necessary
to use in order to turn the iface up, whatever.

So I was playing with the atusb devices and I _think_ I've found a
firmware bug or a hardware bug which is going to be problematic. In
iface.c, when creating the interface, if you set the hardware filters
(set_panid/short/ext_addr()) there is no way you will be able to get a
fully transparent promiscuous mode. I am not saying that the whole
promiscuous mode does not work anymore, I don't really know. What I was
interested in were the acks, and getting them is a real pain. At least,
enabling the promiscuous mode after setting the hw filters will lead to
the acks being dropped immediately while if the promiscuous mode is
enabled first (like on monitor interfaces) the acks are correctly
forwarded by the PHY.

While looking at the history of the drivers, I realized that the
TX_ARET mode was not supported by the firmware in 2015 (that's what you
say in a commit) I have seen no further updates about it so I guess
it's still not available. I don't see any other way to know if a
frame's ack has been received or not reliably.

Do you think I can just ignore the acks during an association in
mac802154? Another idea how to get them? The Atmel datasheet states the
following, which is not encouraging:

	If (Destination Addressing Mode = 0 OR 1) AND (Source
	Addressing Mode = 0) no IRQ_5 (AMI) is generated, refer to
	Section 8.1.2.2 “Frame Control Field (FCF)” on page 80. This
	effectively causes all acknowledgement frames not to be
	announced, which otherwise always pass the fil- ter, regardless
	of whether they are intended for this device or not.

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-09-03  0:08                                         ` Miquel Raynal
@ 2022-09-03 14:20                                           ` Alexander Aring
  2022-09-03 14:31                                             ` Alexander Aring
  2022-09-03 16:05                                             ` Miquel Raynal
  0 siblings, 2 replies; 84+ messages in thread
From: Alexander Aring @ 2022-09-03 14:20 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Fri, Sep 2, 2022 at 8:08 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
...
> >
> > I am sorry, I never looked into Zephyr for reasons... Do they not have
> > something like /proc/interrupts look if you see a counter for your
> > 802.15.4 transceiver?
> >
> > > Also, can you please clarify when are we talking about software and
> > > when about hardware filters.
> > >
> >
> > Hardware filter is currently e.g. promiscuous mode on or off setting.
> > Software filtering is depending which receive path the frame is going
> > and which hardware filter is present which then acts like actually
> > with hardware filtering.
> > I am not sure if this answers this question?
>
> I think my understand gets clearer now that I've digged into Zephyr's
> ieee802154 layer and in the at86rf230 datasheet.
>

okay, I think for zephyr questions you are here on the wrong mailinglist.

> I will answer the previous e-mail but just for not I wanted to add that
> I managed to get Zephyr working, I had to mess around in the code a
> little bit and actually I discovered a net command which is necessary
> to use in order to turn the iface up, whatever.
>

aha.

> So I was playing with the atusb devices and I _think_ I've found a
> firmware bug or a hardware bug which is going to be problematic. In

the firmware is open source, I think it's fine to send patches here (I
did it as well once for do a quick hack to port it to rzusb) the atusb
is "mostly" at the point that they can do open hardware from the
qi-hardware organization.

> iface.c, when creating the interface, if you set the hardware filters
> (set_panid/short/ext_addr()) there is no way you will be able to get a
> fully transparent promiscuous mode. I am not saying that the whole

What is a transparent promiscuous mode?

> promiscuous mode does not work anymore, I don't really know. What I was
> interested in were the acks, and getting them is a real pain. At least,
> enabling the promiscuous mode after setting the hw filters will lead to
> the acks being dropped immediately while if the promiscuous mode is
> enabled first (like on monitor interfaces) the acks are correctly
> forwarded by the PHY.

If we would not disable AACK handling (means we receive a frame with
ack requested bit set we send a ack back) we would ack every frame it
receives (speaking on at86rf233).

>
> While looking at the history of the drivers, I realized that the
> TX_ARET mode was not supported by the firmware in 2015 (that's what you

There exists ARET and AACK, both are mac mechanisms which must be
offloaded on the hardware. Note that those only do "something" if the
ack request bit in the frame is set.

ARET will retransmit if no ack is received after some while, etc.
mostly coupled with CSMA/CA handling. We cannot guarantee such timings
on the Linux layer. btw: mac80211 can also not handle acks on the
software layer, it must be offloaded.

AACK will send a back if a frame with ack request bit was received.

> say in a commit) I have seen no further updates about it so I guess
> it's still not available. I don't see any other way to know if a
> frame's ack has been received or not reliably.

You implemented it for the at86rf230 driver (the spi one which is what
also atusb uses). You implemented the

ctx->trac = IEEE802154_NO_ACK;

which signals the upper layer that if the ack request bit is set, that
there was no ack.

But yea, there is a missing feature for atusb yet which requires
firmware changes as well. Btw: I can imagine that hwsim "fakes" such
offload behaviours.

>
> Do you think I can just ignore the acks during an association in
> mac802154?

No, even we should WARN_ON ack frames in states we don't expect them
because they must be offloaded on hardware.

I am not sure if I am following what is wrong with the trac register
and NO_ACK, this is the information if we got an ack or not. Do you
need to turn off address filters while "an association"?

Another idea how to get them? The Atmel datasheet states the
> following, which is not encouraging:
>
>         If (Destination Addressing Mode = 0 OR 1) AND (Source
>         Addressing Mode = 0) no IRQ_5 (AMI) is generated, refer to
>         Section 8.1.2.2 “Frame Control Field (FCF)” on page 80. This
>         effectively causes all acknowledgement frames not to be
>         announced, which otherwise always pass the fil- ter, regardless
>         of whether they are intended for this device or not.

I hope the answers above are helpful because I don't know how this can
be useful here.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-09-03 14:20                                           ` Alexander Aring
@ 2022-09-03 14:31                                             ` Alexander Aring
  2022-09-03 16:05                                             ` Miquel Raynal
  1 sibling, 0 replies; 84+ messages in thread
From: Alexander Aring @ 2022-09-03 14:31 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Sat, Sep 3, 2022 at 10:20 AM Alexander Aring <aahringo@redhat.com> wrote:
>
> Hi,
>
> On Fri, Sep 2, 2022 at 8:08 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> ...
> > >
> > > I am sorry, I never looked into Zephyr for reasons... Do they not have
> > > something like /proc/interrupts look if you see a counter for your
> > > 802.15.4 transceiver?
> > >
> > > > Also, can you please clarify when are we talking about software and
> > > > when about hardware filters.
> > > >
> > >
> > > Hardware filter is currently e.g. promiscuous mode on or off setting.
> > > Software filtering is depending which receive path the frame is going
> > > and which hardware filter is present which then acts like actually
> > > with hardware filtering.
> > > I am not sure if this answers this question?
> >
> > I think my understand gets clearer now that I've digged into Zephyr's
> > ieee802154 layer and in the at86rf230 datasheet.
> >
>
> okay, I think for zephyr questions you are here on the wrong mailinglist.
>
> > I will answer the previous e-mail but just for not I wanted to add that
> > I managed to get Zephyr working, I had to mess around in the code a
> > little bit and actually I discovered a net command which is necessary
> > to use in order to turn the iface up, whatever.
> >
>
> aha.
>
> > So I was playing with the atusb devices and I _think_ I've found a
> > firmware bug or a hardware bug which is going to be problematic. In
>
> the firmware is open source, I think it's fine to send patches here (I
> did it as well once for do a quick hack to port it to rzusb) the atusb
> is "mostly" at the point that they can do open hardware from the
> qi-hardware organization.
>
> > iface.c, when creating the interface, if you set the hardware filters
> > (set_panid/short/ext_addr()) there is no way you will be able to get a
> > fully transparent promiscuous mode. I am not saying that the whole
>
> What is a transparent promiscuous mode?
>
> > promiscuous mode does not work anymore, I don't really know. What I was
> > interested in were the acks, and getting them is a real pain. At least,
> > enabling the promiscuous mode after setting the hw filters will lead to
> > the acks being dropped immediately while if the promiscuous mode is
> > enabled first (like on monitor interfaces) the acks are correctly
> > forwarded by the PHY.
>
> If we would not disable AACK handling (means we receive a frame with
> ack requested bit set we send a ack back) we would ack every frame it
> receives (speaking on at86rf233).
>
> >
> > While looking at the history of the drivers, I realized that the
> > TX_ARET mode was not supported by the firmware in 2015 (that's what you
>
> There exists ARET and AACK, both are mac mechanisms which must be
> offloaded on the hardware. Note that those only do "something" if the
> ack request bit in the frame is set.
>
> ARET will retransmit if no ack is received after some while, etc.
> mostly coupled with CSMA/CA handling. We cannot guarantee such timings
> on the Linux layer. btw: mac80211 can also not handle acks on the
> software layer, it must be offloaded.
>
> AACK will send a back if a frame with ack request bit was received.

will send an ack back*

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-09-03 14:20                                           ` Alexander Aring
  2022-09-03 14:31                                             ` Alexander Aring
@ 2022-09-03 16:05                                             ` Miquel Raynal
  2022-09-03 18:21                                               ` Alexander Aring
  2022-09-03 19:07                                               ` Alexander Aring
  1 sibling, 2 replies; 84+ messages in thread
From: Miquel Raynal @ 2022-09-03 16:05 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi Alexander,

aahringo@redhat.com wrote on Sat, 3 Sep 2022 10:20:24 -0400:

> Hi,
> 
> On Fri, Sep 2, 2022 at 8:08 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> ...
> > >
> > > I am sorry, I never looked into Zephyr for reasons... Do they not have
> > > something like /proc/interrupts look if you see a counter for your
> > > 802.15.4 transceiver?
> > >  
> > > > Also, can you please clarify when are we talking about software and
> > > > when about hardware filters.
> > > >  
> > >
> > > Hardware filter is currently e.g. promiscuous mode on or off setting.
> > > Software filtering is depending which receive path the frame is going
> > > and which hardware filter is present which then acts like actually
> > > with hardware filtering.
> > > I am not sure if this answers this question?  
> >
> > I think my understand gets clearer now that I've digged into Zephyr's
> > ieee802154 layer and in the at86rf230 datasheet.
> >  
> 
> okay, I think for zephyr questions you are here on the wrong mailinglist.
> 
> > I will answer the previous e-mail but just for not I wanted to add that
> > I managed to get Zephyr working, I had to mess around in the code a
> > little bit and actually I discovered a net command which is necessary
> > to use in order to turn the iface up, whatever.
> >  
> 
> aha.
> 
> > So I was playing with the atusb devices and I _think_ I've found a
> > firmware bug or a hardware bug which is going to be problematic. In  
> 
> the firmware is open source, I think it's fine to send patches here (I
> did it as well once for do a quick hack to port it to rzusb) the atusb
> is "mostly" at the point that they can do open hardware from the
> qi-hardware organization.
> 
> > iface.c, when creating the interface, if you set the hardware filters
> > (set_panid/short/ext_addr()) there is no way you will be able to get a
> > fully transparent promiscuous mode. I am not saying that the whole  
> 
> What is a transparent promiscuous mode?

I observe something very weird:

A/ If at start up time we set promisc_mode(true) and then we set the hw
address filters, all the frames are forwarded to the MAC.

B/ If at start up time we set the hw address filters and then set
promisc_mode(true), there is some filtering happening (like the Acks
which are dropped by the PHY.

I need to investigate this further because I don't get why in case B we
don't have the same behavior than in case A.

> > promiscuous mode does not work anymore, I don't really know. What I was
> > interested in were the acks, and getting them is a real pain. At least,
> > enabling the promiscuous mode after setting the hw filters will lead to
> > the acks being dropped immediately while if the promiscuous mode is
> > enabled first (like on monitor interfaces) the acks are correctly
> > forwarded by the PHY.  
> 
> If we would not disable AACK handling (means we receive a frame with
> ack requested bit set we send a ack back) we would ack every frame it
> receives (speaking on at86rf233).

Yes, but when sending MAC frames I would like to:
- be in promiscuous mode in Rx (tx paused) in order for the MAC to be
  aware of the acks being received (unless there is another way to do
  that, see below)
- still ack the received frames automatically

Unless we decide that we must only ack the expected frames manually?

> > While looking at the history of the drivers, I realized that the
> > TX_ARET mode was not supported by the firmware in 2015 (that's what you  
> 
> There exists ARET and AACK, both are mac mechanisms which must be
> offloaded on the hardware. Note that those only do "something" if the
> ack request bit in the frame is set.

Absolutely (for the record, that's also an issue I had with Zephyr, I
had to use the shell to explicitly ask the AR bit to be set in the
outgoing frames, even though this in most MAC frames this is not a user
choice, it's expected by the spec).

> ARET will retransmit if no ack is received after some while, etc.
> mostly coupled with CSMA/CA handling. We cannot guarantee such timings
> on the Linux layer. btw: mac80211 can also not handle acks on the
> software layer, it must be offloaded.

On the Tx side, when sending eg. an association request or an
association response, I must expect and wait for an ack. This is
what I am struggling to do. How can I know that a frame which I just
transmitted has been acked? Bonus points, how can I do that in such a
way that it will work with other devices? (hints below)

> AACK will send a back if a frame with ack request bit was received.
> 
> > say in a commit) I have seen no further updates about it so I guess
> > it's still not available. I don't see any other way to know if a
> > frame's ack has been received or not reliably.  
> 
> You implemented it for the at86rf230 driver (the spi one which is what
> also atusb uses). You implemented the
> 
> ctx->trac = IEEE802154_NO_ACK;
> 
> which signals the upper layer that if the ack request bit is set, that
> there was no ack.
> 
> But yea, there is a missing feature for atusb yet which requires
> firmware changes as well.

:'(

Let's say I don't have the time to update the firmware ;). I also assume
that other transceivers (or even the drivers) might be limited on this
regard as well. How should I handle those "I should wait for the ack to
be received" situation while trying to associate?

The tricky case is the device receiving the ASSOC_REQ:
- the request is received
- an ack must be sent (this is okay in most cases I guess)
- the device must send an association response (also ok)
- and wait for the response to be acked...
	* either I use the promisc mode when sending the response
	  (because of possible race conditions) and I expect the ack to
	  be forwarded to the MAC
		-> This does not work on atusb, enabling promiscuous
		mode after the init does not turn the PHY into
		promiscuous mode as expected (discussed above)
	* or I don't turn the PHY in promiscuous mode and I expect it
	  to return a clear status about if the ACK was received
		-> But this seem to be unsupported with the current
		ATUSB firmware, I fear other devices could have similar
		limitations
	* or I just assume the acks are received blindly
		-> Not sure this is robust enough?

What is your "less worse" choice?

> Btw: I can imagine that hwsim "fakes" such
> offload behaviours.

My current implementation actually did handle all the acks (waiting for
them and sending them) from the MAC. I'm currently migrating the ack
sending part to the hw. For the reception, that's the big question.

> > Do you think I can just ignore the acks during an association in
> > mac802154?  
> 
> No, even we should WARN_ON ack frames in states we don't expect them
> because they must be offloaded on hardware.
> 
> I am not sure if I am following what is wrong with the trac register
> and NO_ACK, this is the information if we got an ack or not. Do you
> need to turn off address filters while "an association"?

If we have access to the TRAC register, I believe we no longer need to
turn off address filters.

> Another idea how to get them? The Atmel datasheet states the
> > following, which is not encouraging:
> >
> >         If (Destination Addressing Mode = 0 OR 1) AND (Source
> >         Addressing Mode = 0) no IRQ_5 (AMI) is generated, refer to
> >         Section 8.1.2.2 “Frame Control Field (FCF)” on page 80. This
> >         effectively causes all acknowledgement frames not to be
> >         announced, which otherwise always pass the fil- ter, regardless
> >         of whether they are intended for this device or not.  
> 
> I hope the answers above are helpful because I don't know how this can
> be useful here.
> 
> - Alex
> 


Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-09-03 16:05                                             ` Miquel Raynal
@ 2022-09-03 18:21                                               ` Alexander Aring
  2022-09-03 18:29                                                 ` Alexander Aring
  2022-09-03 19:07                                               ` Alexander Aring
  1 sibling, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-09-03 18:21 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Sat, Sep 3, 2022 at 12:06 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> Hi Alexander,
>
> aahringo@redhat.com wrote on Sat, 3 Sep 2022 10:20:24 -0400:
>
> > Hi,
> >
> > On Fri, Sep 2, 2022 at 8:08 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > ...
> > > >
> > > > I am sorry, I never looked into Zephyr for reasons... Do they not have
> > > > something like /proc/interrupts look if you see a counter for your
> > > > 802.15.4 transceiver?
> > > >
> > > > > Also, can you please clarify when are we talking about software and
> > > > > when about hardware filters.
> > > > >
> > > >
> > > > Hardware filter is currently e.g. promiscuous mode on or off setting.
> > > > Software filtering is depending which receive path the frame is going
> > > > and which hardware filter is present which then acts like actually
> > > > with hardware filtering.
> > > > I am not sure if this answers this question?
> > >
> > > I think my understand gets clearer now that I've digged into Zephyr's
> > > ieee802154 layer and in the at86rf230 datasheet.
> > >
> >
> > okay, I think for zephyr questions you are here on the wrong mailinglist.
> >
> > > I will answer the previous e-mail but just for not I wanted to add that
> > > I managed to get Zephyr working, I had to mess around in the code a
> > > little bit and actually I discovered a net command which is necessary
> > > to use in order to turn the iface up, whatever.
> > >
> >
> > aha.
> >
> > > So I was playing with the atusb devices and I _think_ I've found a
> > > firmware bug or a hardware bug which is going to be problematic. In
> >
> > the firmware is open source, I think it's fine to send patches here (I
> > did it as well once for do a quick hack to port it to rzusb) the atusb
> > is "mostly" at the point that they can do open hardware from the
> > qi-hardware organization.
> >
> > > iface.c, when creating the interface, if you set the hardware filters
> > > (set_panid/short/ext_addr()) there is no way you will be able to get a
> > > fully transparent promiscuous mode. I am not saying that the whole
> >
> > What is a transparent promiscuous mode?
>
> I observe something very weird:
>
> A/ If at start up time we set promisc_mode(true) and then we set the hw
> address filters, all the frames are forwarded to the MAC.
>
> B/ If at start up time we set the hw address filters and then set
> promisc_mode(true), there is some filtering happening (like the Acks
> which are dropped by the PHY.
>
> I need to investigate this further because I don't get why in case B we
> don't have the same behavior than in case A.
>

Looking in the datasheet I see only set address filters -> then
setting promiscuous mode is specified? Not the other way around...

> > > promiscuous mode does not work anymore, I don't really know. What I was
> > > interested in were the acks, and getting them is a real pain. At least,
> > > enabling the promiscuous mode after setting the hw filters will lead to
> > > the acks being dropped immediately while if the promiscuous mode is
> > > enabled first (like on monitor interfaces) the acks are correctly
> > > forwarded by the PHY.
> >
> > If we would not disable AACK handling (means we receive a frame with
> > ack requested bit set we send a ack back) we would ack every frame it
> > receives (speaking on at86rf233).
>
> Yes, but when sending MAC frames I would like to:
> - be in promiscuous mode in Rx (tx paused) in order for the MAC to be
>   aware of the acks being received (unless there is another way to do
>   that, see below)
> - still ack the received frames automatically
>
> Unless we decide that we must only ack the expected frames manually?
>

We can't handle ack frames on mac802154 in my opinion. Or what does
manually mean?

Is the ack frame required as a mac command operation or as a response
to a transmitted frame because the other side will do retransmissions
if they don't see an ack back? The second case is not possible to
implement on mac802154, it must be offloaded.

> > > While looking at the history of the drivers, I realized that the
> > > TX_ARET mode was not supported by the firmware in 2015 (that's what you
> >
> > There exists ARET and AACK, both are mac mechanisms which must be
> > offloaded on the hardware. Note that those only do "something" if the
> > ack request bit in the frame is set.
>
> Absolutely (for the record, that's also an issue I had with Zephyr, I
> had to use the shell to explicitly ask the AR bit to be set in the
> outgoing frames, even though this in most MAC frames this is not a user
> choice, it's expected by the spec).
>

fyi: we have also a default_ackreq behaviour if we set the ack frame
on all data frames or not. However it's currently set to not set the
ackreq bit because most hardware outside can't handle it (even if
required by the spec). If you have a requirement to set ack request
bit then do it, if there is hardware outside which cannot handle it,
it's their problem. However the dataframes which are sent via user
space socket depending on the use case if they want to set it or not
but if they set it you need to know your network.

> > ARET will retransmit if no ack is received after some while, etc.
> > mostly coupled with CSMA/CA handling. We cannot guarantee such timings
> > on the Linux layer. btw: mac80211 can also not handle acks on the
> > software layer, it must be offloaded.
>
> On the Tx side, when sending eg. an association request or an
> association response, I must expect and wait for an ack. This is
> what I am struggling to do. How can I know that a frame which I just
> transmitted has been acked? Bonus points, how can I do that in such a
> way that it will work with other devices? (hints below)
>

You can't do this in mac802154 if there is a timing critical
requirement here. Is there a timing critical requirement here?

> > AACK will send a back if a frame with ack request bit was received.
> >
> > > say in a commit) I have seen no further updates about it so I guess
> > > it's still not available. I don't see any other way to know if a
> > > frame's ack has been received or not reliably.
> >
> > You implemented it for the at86rf230 driver (the spi one which is what
> > also atusb uses). You implemented the
> >
> > ctx->trac = IEEE802154_NO_ACK;
> >
> > which signals the upper layer that if the ack request bit is set, that
> > there was no ack.
> >
> > But yea, there is a missing feature for atusb yet which requires
> > firmware changes as well.
>
> :'(
>
> Let's say I don't have the time to update the firmware ;). I also assume
> that other transceivers (or even the drivers) might be limited on this
> regard as well. How should I handle those "I should wait for the ack to
> be received" situation while trying to associate?
>

If other transceivers cannot handle giving us feedback if ack was
received or not and we have the mandatory requirement to know it, it
is poor hardware/driver. As I said if the spec requires to check on an
ack or not we need to get his information, if the hardware/driver
can't deliver this... then just assume an ACK was received as it
returns TX_SUCCESS (or whatever the return value was). I said before
that some hardware will act weird if they don't support it.

> The tricky case is the device receiving the ASSOC_REQ:
> - the request is received
> - an ack must be sent (this is okay in most cases I guess)
> - the device must send an association response (also ok)
> - and wait for the response to be acked...
>         * either I use the promisc mode when sending the response
>           (because of possible race conditions) and I expect the ack to
>           be forwarded to the MAC
>                 -> This does not work on atusb, enabling promiscuous
>                 mode after the init does not turn the PHY into
>                 promiscuous mode as expected (discussed above)
>         * or I don't turn the PHY in promiscuous mode and I expect it
>           to return a clear status about if the ACK was received
>                 -> But this seem to be unsupported with the current
>                 ATUSB firmware, I fear other devices could have similar
>                 limitations
>         * or I just assume the acks are received blindly
>                 -> Not sure this is robust enough?
>

Assume you always get an ack back until somebody implements this
feature in their driver (It's already implemented so as they return
TX_SUCCESS). We cannot do much more I think... it is not robust but
then somebody needs to update the driver/firmware.

It's more weird if the otherside does not support AACK, because ARET
will send them 3 times (by default) the same frame. That's why we have
the policy to not set the ackreq bit if it's not required.

> What is your "less worse" choice?
>
> > Btw: I can imagine that hwsim "fakes" such
> > offload behaviours.
>
> My current implementation actually did handle all the acks (waiting for
> them and sending them) from the MAC. I'm currently migrating the ack
> sending part to the hw. For the reception, that's the big question.
>

In my opinion we should never deal with ack frames on mac802154 level,
neither on hwsim, this is an offloaded functionality. What I have in
mind is to fake a "TX_NO_ACK" return value as a probability parameter
to return it sometimes. E.g. as netem and drop rate, etc. Then we
could do some testing with it.

> > > Do you think I can just ignore the acks during an association in
> > > mac802154?
> >
> > No, even we should WARN_ON ack frames in states we don't expect them
> > because they must be offloaded on hardware.
> >
> > I am not sure if I am following what is wrong with the trac register
> > and NO_ACK, this is the information if we got an ack or not. Do you
> > need to turn off address filters while "an association"?
>
> If we have access to the TRAC register, I believe we no longer need to
> turn off address filters.
>

That sounds good.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-09-03 18:21                                               ` Alexander Aring
@ 2022-09-03 18:29                                                 ` Alexander Aring
  0 siblings, 0 replies; 84+ messages in thread
From: Alexander Aring @ 2022-09-03 18:29 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni

Hi,

On Sat, Sep 3, 2022 at 2:21 PM Alexander Aring <aahringo@redhat.com> wrote:
...
>
> Assume you always get an ack back until somebody implements this
> feature in their driver (It's already implemented so as they return
> TX_SUCCESS). We cannot do much more I think... it is not robust but
> then somebody needs to update the driver/firmware.
>
> It's more weird if the otherside does not support AACK, because ARET
> will send them 3 times (by default) the same frame. That's why we have
> the policy to not set the ackreq bit if it's not required.
>
> > What is your "less worse" choice?
> >
> > > Btw: I can imagine that hwsim "fakes" such
> > > offload behaviours.
> >
> > My current implementation actually did handle all the acks (waiting for
> > them and sending them) from the MAC. I'm currently migrating the ack
> > sending part to the hw. For the reception, that's the big question.
> >
>
> In my opinion we should never deal with ack frames on mac802154 level,
> neither on hwsim, this is an offloaded functionality. What I have in

* except of course in cases of monitors, but monitors really aren't
part of the network and they are sniffers... A monitor can indeed send
frames out, which could cause a lot of trouble in the network if you
want to. It's a playground thing to do experiments... Here we never
analyze any payload received and forward it directly to the user, it's
also a kind of kernel bypass. I know people run some user space stacks
with it (including myself) but they get problems until it gets into
e.g. ackknowledge handling.

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-09-03 16:05                                             ` Miquel Raynal
  2022-09-03 18:21                                               ` Alexander Aring
@ 2022-09-03 19:07                                               ` Alexander Aring
  2022-09-03 19:10                                                 ` Alexander Aring
  1 sibling, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-09-03 19:07 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni, werner

Hi,

On Sat, Sep 3, 2022 at 12:06 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
...
>
> On the Tx side, when sending eg. an association request or an
> association response, I must expect and wait for an ack. This is
> what I am struggling to do. How can I know that a frame which I just
> transmitted has been acked? Bonus points, how can I do that in such a
> way that it will work with other devices? (hints below)
>
> > AACK will send a back if a frame with ack request bit was received.
> >
> > > say in a commit) I have seen no further updates about it so I guess
> > > it's still not available. I don't see any other way to know if a
> > > frame's ack has been received or not reliably.
> >
> > You implemented it for the at86rf230 driver (the spi one which is what
> > also atusb uses). You implemented the
> >
> > ctx->trac = IEEE802154_NO_ACK;
> >
> > which signals the upper layer that if the ack request bit is set, that
> > there was no ack.
> >
> > But yea, there is a missing feature for atusb yet which requires
> > firmware changes as well.
>
> :'(

There is a sequence handling in tx done on atusb firmware and I think
it should be pretty easy to add a byte for trac status.

diff --git a/atusb/fw/mac.c b/atusb/fw/mac.c
index 835002c..156bd95 100644
--- a/atusb/fw/mac.c
+++ b/atusb/fw/mac.c
@@ -116,7 +116,7 @@ static void receive_frame(void)

 static bool handle_irq(void)
 {
-       uint8_t irq;
+       uint8_t irq, data[2];

        irq = reg_read(REG_IRQ_STATUS);
        if (!(irq & IRQ_TRX_END))
@@ -124,7 +124,15 @@ static bool handle_irq(void)

        if (txing) {
                if (eps[1].state == EP_IDLE) {
-                       usb_send(&eps[1], &this_seq, 1, tx_ack_done, NULL);
+                       data[0] = tx_ack_done;
+
+                       spi_begin();
+                       spi_io(REG_TRX_STATE);
+
+                       data[1] = spi_recv();
+                       spi_end();
+
+                       usb_send(&eps[1], &this_seq, sizeof(data), data, NULL);
                } else {
                        queued_tx_ack = 1;
                        queued_seq = this_seq;

Did not test it, but maybe something in this direction?

cc Werner Almesberger here, he did most of the atusb hardware and firmware.

- Alex


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-09-03 19:07                                               ` Alexander Aring
@ 2022-09-03 19:10                                                 ` Alexander Aring
  2022-09-03 19:40                                                   ` Alexander Aring
  0 siblings, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-09-03 19:10 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni, werner

On Sat, Sep 3, 2022 at 3:07 PM Alexander Aring <aahringo@redhat.com> wrote:
>
> Hi,
>
> On Sat, Sep 3, 2022 at 12:06 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> ...
> >
> > On the Tx side, when sending eg. an association request or an
> > association response, I must expect and wait for an ack. This is
> > what I am struggling to do. How can I know that a frame which I just
> > transmitted has been acked? Bonus points, how can I do that in such a
> > way that it will work with other devices? (hints below)
> >
> > > AACK will send a back if a frame with ack request bit was received.
> > >
> > > > say in a commit) I have seen no further updates about it so I guess
> > > > it's still not available. I don't see any other way to know if a
> > > > frame's ack has been received or not reliably.
> > >
> > > You implemented it for the at86rf230 driver (the spi one which is what
> > > also atusb uses). You implemented the
> > >
> > > ctx->trac = IEEE802154_NO_ACK;
> > >
> > > which signals the upper layer that if the ack request bit is set, that
> > > there was no ack.
> > >
> > > But yea, there is a missing feature for atusb yet which requires
> > > firmware changes as well.
> >
> > :'(
>
> There is a sequence handling in tx done on atusb firmware and I think
> it should be pretty easy to add a byte for trac status.
>
> diff --git a/atusb/fw/mac.c b/atusb/fw/mac.c
> index 835002c..156bd95 100644
> --- a/atusb/fw/mac.c
> +++ b/atusb/fw/mac.c
> @@ -116,7 +116,7 @@ static void receive_frame(void)
>
>  static bool handle_irq(void)
>  {
> -       uint8_t irq;
> +       uint8_t irq, data[2];
>
>         irq = reg_read(REG_IRQ_STATUS);
>         if (!(irq & IRQ_TRX_END))
> @@ -124,7 +124,15 @@ static bool handle_irq(void)
>
>         if (txing) {
>                 if (eps[1].state == EP_IDLE) {
> -                       usb_send(&eps[1], &this_seq, 1, tx_ack_done, NULL);
> +                       data[0] = tx_ack_done;
> +
> +                       spi_begin();
> +                       spi_io(REG_TRX_STATE);
> +
> +                       data[1] = spi_recv();
> +                       spi_end();

data[1] = reg_read(REG_TRX_STATE) as seen above for REG_IRQ_STATUS
would be better here...

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-09-03 19:10                                                 ` Alexander Aring
@ 2022-09-03 19:40                                                   ` Alexander Aring
  2022-09-05  3:16                                                     ` Miquel Raynal
  0 siblings, 1 reply; 84+ messages in thread
From: Alexander Aring @ 2022-09-03 19:40 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni, werner

Hi,

On Sat, Sep 3, 2022 at 3:10 PM Alexander Aring <aahringo@redhat.com> wrote:
>
> On Sat, Sep 3, 2022 at 3:07 PM Alexander Aring <aahringo@redhat.com> wrote:
> >
> > Hi,
> >
> > On Sat, Sep 3, 2022 at 12:06 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > ...
> > >
> > > On the Tx side, when sending eg. an association request or an
> > > association response, I must expect and wait for an ack. This is
> > > what I am struggling to do. How can I know that a frame which I just
> > > transmitted has been acked? Bonus points, how can I do that in such a
> > > way that it will work with other devices? (hints below)
> > >
> > > > AACK will send a back if a frame with ack request bit was received.
> > > >
> > > > > say in a commit) I have seen no further updates about it so I guess
> > > > > it's still not available. I don't see any other way to know if a
> > > > > frame's ack has been received or not reliably.
> > > >
> > > > You implemented it for the at86rf230 driver (the spi one which is what
> > > > also atusb uses). You implemented the
> > > >
> > > > ctx->trac = IEEE802154_NO_ACK;
> > > >
> > > > which signals the upper layer that if the ack request bit is set, that
> > > > there was no ack.
> > > >
> > > > But yea, there is a missing feature for atusb yet which requires
> > > > firmware changes as well.
> > >
> > > :'(
> >
> > There is a sequence handling in tx done on atusb firmware and I think
> > it should be pretty easy to add a byte for trac status.
> >
> > diff --git a/atusb/fw/mac.c b/atusb/fw/mac.c
> > index 835002c..156bd95 100644
> > --- a/atusb/fw/mac.c
> > +++ b/atusb/fw/mac.c
> > @@ -116,7 +116,7 @@ static void receive_frame(void)
> >
> >  static bool handle_irq(void)
> >  {
> > -       uint8_t irq;
> > +       uint8_t irq, data[2];
> >
> >         irq = reg_read(REG_IRQ_STATUS);
> >         if (!(irq & IRQ_TRX_END))
> > @@ -124,7 +124,15 @@ static bool handle_irq(void)
> >
> >         if (txing) {
> >                 if (eps[1].state == EP_IDLE) {
> > -                       usb_send(&eps[1], &this_seq, 1, tx_ack_done, NULL);
> > +                       data[0] = tx_ack_done;
> > +
> > +                       spi_begin();
> > +                       spi_io(REG_TRX_STATE);
> > +
> > +                       data[1] = spi_recv();
> > +                       spi_end();
>
> data[1] = reg_read(REG_TRX_STATE) as seen above for REG_IRQ_STATUS
> would be better here...
>

after digging the code more, there is another queue case which we
should handle, also correct using buffer parameter instead of the
callback parameter which was stupid... However I think the direction
is clear. Sorry for the spam.

diff --git a/atusb/fw/mac.c b/atusb/fw/mac.c
index 835002c..b52ba1a 100644
--- a/atusb/fw/mac.c
+++ b/atusb/fw/mac.c
@@ -32,7 +32,7 @@ static uint8_t tx_buf[MAX_PSDU];
 static uint8_t tx_size = 0;
 static bool txing = 0;
 static bool queued_tx_ack = 0;
-static uint8_t next_seq, this_seq, queued_seq;
+static uint8_t next_seq, this_seq, queued_seq, queued_tx_trac;


 /* ----- Receive buffer management ----------------------------------------- */
@@ -57,6 +57,7 @@ static void tx_ack_done(void *user);
 static void usb_next(void)
 {
        const uint8_t *buf;
+       uint8_t data[2];

        if (rx_in != rx_out) {
                buf = rx_buf[rx_out];
@@ -65,7 +66,9 @@ static void usb_next(void)
        }

        if (queued_tx_ack) {
-               usb_send(&eps[1], &queued_seq, 1, tx_ack_done, NULL);
+               data[0] = queued_seq;
+               data[1] = queued_tx_trac;
+               usb_send(&eps[1], data, sizeof(data), tx_ack_done, NULL);
                queued_tx_ack = 0;
        }
 }
@@ -116,7 +119,7 @@ static void receive_frame(void)

 static bool handle_irq(void)
 {
-       uint8_t irq;
+       uint8_t irq, data[2];

        irq = reg_read(REG_IRQ_STATUS);
        if (!(irq & IRQ_TRX_END))
@@ -124,10 +127,13 @@ static bool handle_irq(void)

        if (txing) {
                if (eps[1].state == EP_IDLE) {
-                       usb_send(&eps[1], &this_seq, 1, tx_ack_done, NULL);
+                       data[0] = this_seq;
+                       data[1] = reg_read(REG_TRX_STATE);
+                       usb_send(&eps[1], data, sizeof(data),
tx_ack_done, NULL);
                } else {
                        queued_tx_ack = 1;
                        queued_seq = this_seq;
+                       queued_tx_trac = reg_read(REG_TRX_STATE);
                }
                txing = 0;
                return 1;


^ permalink raw reply related	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-09-03 19:40                                                   ` Alexander Aring
@ 2022-09-05  3:16                                                     ` Miquel Raynal
  2022-09-05 22:35                                                       ` Alexander Aring
  0 siblings, 1 reply; 84+ messages in thread
From: Miquel Raynal @ 2022-09-05  3:16 UTC (permalink / raw)
  To: Alexander Aring
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni, werner

Hi Alexander,

aahringo@redhat.com wrote on Sat, 3 Sep 2022 15:40:35 -0400:

> Hi,
> 
> On Sat, Sep 3, 2022 at 3:10 PM Alexander Aring <aahringo@redhat.com> wrote:
> >
> > On Sat, Sep 3, 2022 at 3:07 PM Alexander Aring <aahringo@redhat.com> wrote:  
> > >
> > > Hi,
> > >
> > > On Sat, Sep 3, 2022 at 12:06 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > ...  
> > > >
> > > > On the Tx side, when sending eg. an association request or an
> > > > association response, I must expect and wait for an ack. This is
> > > > what I am struggling to do. How can I know that a frame which I just
> > > > transmitted has been acked? Bonus points, how can I do that in such a
> > > > way that it will work with other devices? (hints below)
> > > >  
> > > > > AACK will send a back if a frame with ack request bit was received.
> > > > >  
> > > > > > say in a commit) I have seen no further updates about it so I guess
> > > > > > it's still not available. I don't see any other way to know if a
> > > > > > frame's ack has been received or not reliably.  
> > > > >
> > > > > You implemented it for the at86rf230 driver (the spi one which is what
> > > > > also atusb uses). You implemented the
> > > > >
> > > > > ctx->trac = IEEE802154_NO_ACK;
> > > > >
> > > > > which signals the upper layer that if the ack request bit is set, that
> > > > > there was no ack.
> > > > >
> > > > > But yea, there is a missing feature for atusb yet which requires
> > > > > firmware changes as well.  
> > > >
> > > > :'(  
> > >
> > > There is a sequence handling in tx done on atusb firmware and I think
> > > it should be pretty easy to add a byte for trac status.
> > >
> > > diff --git a/atusb/fw/mac.c b/atusb/fw/mac.c
> > > index 835002c..156bd95 100644
> > > --- a/atusb/fw/mac.c
> > > +++ b/atusb/fw/mac.c
> > > @@ -116,7 +116,7 @@ static void receive_frame(void)
> > >
> > >  static bool handle_irq(void)
> > >  {
> > > -       uint8_t irq;
> > > +       uint8_t irq, data[2];
> > >
> > >         irq = reg_read(REG_IRQ_STATUS);
> > >         if (!(irq & IRQ_TRX_END))
> > > @@ -124,7 +124,15 @@ static bool handle_irq(void)
> > >
> > >         if (txing) {
> > >                 if (eps[1].state == EP_IDLE) {
> > > -                       usb_send(&eps[1], &this_seq, 1, tx_ack_done, NULL);
> > > +                       data[0] = tx_ack_done;
> > > +
> > > +                       spi_begin();
> > > +                       spi_io(REG_TRX_STATE);
> > > +
> > > +                       data[1] = spi_recv();
> > > +                       spi_end();  
> >
> > data[1] = reg_read(REG_TRX_STATE) as seen above for REG_IRQ_STATUS
> > would be better here...
> >  
> 
> after digging the code more, there is another queue case which we
> should handle, also correct using buffer parameter instead of the
> callback parameter which was stupid... However I think the direction
> is clear. Sorry for the spam.

Don't be, your feedback is just super useful.

> diff --git a/atusb/fw/mac.c b/atusb/fw/mac.c
> index 835002c..b52ba1a 100644
> --- a/atusb/fw/mac.c
> +++ b/atusb/fw/mac.c
> @@ -32,7 +32,7 @@ static uint8_t tx_buf[MAX_PSDU];
>  static uint8_t tx_size = 0;
>  static bool txing = 0;
>  static bool queued_tx_ack = 0;
> -static uint8_t next_seq, this_seq, queued_seq;
> +static uint8_t next_seq, this_seq, queued_seq, queued_tx_trac;
> 
> 
>  /* ----- Receive buffer management ----------------------------------------- */
> @@ -57,6 +57,7 @@ static void tx_ack_done(void *user);
>  static void usb_next(void)
>  {
>         const uint8_t *buf;
> +       uint8_t data[2];
> 
>         if (rx_in != rx_out) {
>                 buf = rx_buf[rx_out];
> @@ -65,7 +66,9 @@ static void usb_next(void)
>         }
> 
>         if (queued_tx_ack) {
> -               usb_send(&eps[1], &queued_seq, 1, tx_ack_done, NULL);
> +               data[0] = queued_seq;
> +               data[1] = queued_tx_trac;
> +               usb_send(&eps[1], data, sizeof(data), tx_ack_done, NULL);
>                 queued_tx_ack = 0;
>         }
>  }
> @@ -116,7 +119,7 @@ static void receive_frame(void)
> 
>  static bool handle_irq(void)
>  {
> -       uint8_t irq;
> +       uint8_t irq, data[2];

I don't know why, but defining data on the stack just does not work.
Defining it above with the other static variables is okay. I won't
fight more for "today" but if someone has an explanation I am all hears.

>         irq = reg_read(REG_IRQ_STATUS);
>         if (!(irq & IRQ_TRX_END))
> @@ -124,10 +127,13 @@ static bool handle_irq(void)
> 
>         if (txing) {
>                 if (eps[1].state == EP_IDLE) {
> -                       usb_send(&eps[1], &this_seq, 1, tx_ack_done, NULL);
> +                       data[0] = this_seq;
> +                       data[1] = reg_read(REG_TRX_STATE);
> +                       usb_send(&eps[1], data, sizeof(data),
> tx_ack_done, NULL);
>                 } else {
>                         queued_tx_ack = 1;
>                         queued_seq = this_seq;
> +                       queued_tx_trac = reg_read(REG_TRX_STATE);
>                 }
>                 txing = 0;
>                 return 1;
> 


Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces
  2022-09-05  3:16                                                     ` Miquel Raynal
@ 2022-09-05 22:35                                                       ` Alexander Aring
  0 siblings, 0 replies; 84+ messages in thread
From: Alexander Aring @ 2022-09-05 22:35 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Alexander Aring, Stefan Schmidt, linux-wpan - ML,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
	Network Development, David Girault, Romuald Despres,
	Frederic Blain, Nicolas Schodet, Thomas Petazzoni, werner

Hi,

On Sun, Sep 4, 2022 at 11:16 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> Hi Alexander,
>
> aahringo@redhat.com wrote on Sat, 3 Sep 2022 15:40:35 -0400:
>
> > Hi,
> >
> > On Sat, Sep 3, 2022 at 3:10 PM Alexander Aring <aahringo@redhat.com> wrote:
> > >
> > > On Sat, Sep 3, 2022 at 3:07 PM Alexander Aring <aahringo@redhat.com> wrote:
> > > >
> > > > Hi,
> > > >
> > > > On Sat, Sep 3, 2022 at 12:06 PM Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > > > ...
> > > > >
> > > > > On the Tx side, when sending eg. an association request or an
> > > > > association response, I must expect and wait for an ack. This is
> > > > > what I am struggling to do. How can I know that a frame which I just
> > > > > transmitted has been acked? Bonus points, how can I do that in such a
> > > > > way that it will work with other devices? (hints below)
> > > > >
> > > > > > AACK will send a back if a frame with ack request bit was received.
> > > > > >
> > > > > > > say in a commit) I have seen no further updates about it so I guess
> > > > > > > it's still not available. I don't see any other way to know if a
> > > > > > > frame's ack has been received or not reliably.
> > > > > >
> > > > > > You implemented it for the at86rf230 driver (the spi one which is what
> > > > > > also atusb uses). You implemented the
> > > > > >
> > > > > > ctx->trac = IEEE802154_NO_ACK;
> > > > > >
> > > > > > which signals the upper layer that if the ack request bit is set, that
> > > > > > there was no ack.
> > > > > >
> > > > > > But yea, there is a missing feature for atusb yet which requires
> > > > > > firmware changes as well.
> > > > >
> > > > > :'(
> > > >
> > > > There is a sequence handling in tx done on atusb firmware and I think
> > > > it should be pretty easy to add a byte for trac status.
> > > >
> > > > diff --git a/atusb/fw/mac.c b/atusb/fw/mac.c
> > > > index 835002c..156bd95 100644
> > > > --- a/atusb/fw/mac.c
> > > > +++ b/atusb/fw/mac.c
> > > > @@ -116,7 +116,7 @@ static void receive_frame(void)
> > > >
> > > >  static bool handle_irq(void)
> > > >  {
> > > > -       uint8_t irq;
> > > > +       uint8_t irq, data[2];
> > > >
> > > >         irq = reg_read(REG_IRQ_STATUS);
> > > >         if (!(irq & IRQ_TRX_END))
> > > > @@ -124,7 +124,15 @@ static bool handle_irq(void)
> > > >
> > > >         if (txing) {
> > > >                 if (eps[1].state == EP_IDLE) {
> > > > -                       usb_send(&eps[1], &this_seq, 1, tx_ack_done, NULL);
> > > > +                       data[0] = tx_ack_done;
> > > > +
> > > > +                       spi_begin();
> > > > +                       spi_io(REG_TRX_STATE);
> > > > +
> > > > +                       data[1] = spi_recv();
> > > > +                       spi_end();
> > >
> > > data[1] = reg_read(REG_TRX_STATE) as seen above for REG_IRQ_STATUS
> > > would be better here...
> > >
> >
> > after digging the code more, there is another queue case which we
> > should handle, also correct using buffer parameter instead of the
> > callback parameter which was stupid... However I think the direction
> > is clear. Sorry for the spam.
>
> Don't be, your feedback is just super useful.
>
> > diff --git a/atusb/fw/mac.c b/atusb/fw/mac.c
> > index 835002c..b52ba1a 100644
> > --- a/atusb/fw/mac.c
> > +++ b/atusb/fw/mac.c
> > @@ -32,7 +32,7 @@ static uint8_t tx_buf[MAX_PSDU];
> >  static uint8_t tx_size = 0;
> >  static bool txing = 0;
> >  static bool queued_tx_ack = 0;
> > -static uint8_t next_seq, this_seq, queued_seq;
> > +static uint8_t next_seq, this_seq, queued_seq, queued_tx_trac;
> >
> >
> >  /* ----- Receive buffer management ----------------------------------------- */
> > @@ -57,6 +57,7 @@ static void tx_ack_done(void *user);
> >  static void usb_next(void)
> >  {
> >         const uint8_t *buf;
> > +       uint8_t data[2];
> >
> >         if (rx_in != rx_out) {
> >                 buf = rx_buf[rx_out];
> > @@ -65,7 +66,9 @@ static void usb_next(void)
> >         }
> >
> >         if (queued_tx_ack) {
> > -               usb_send(&eps[1], &queued_seq, 1, tx_ack_done, NULL);
> > +               data[0] = queued_seq;
> > +               data[1] = queued_tx_trac;
> > +               usb_send(&eps[1], data, sizeof(data), tx_ack_done, NULL);

This is also broken, see below.

> >                 queued_tx_ack = 0;
> >         }
> >  }
> > @@ -116,7 +119,7 @@ static void receive_frame(void)
> >
> >  static bool handle_irq(void)
> >  {
> > -       uint8_t irq;
> > +       uint8_t irq, data[2];
>
> I don't know why, but defining data on the stack just does not work.
> Defining it above with the other static variables is okay. I won't
> fight more for "today" but if someone has an explanation I am all hears.

I can explain it... following the usb_send() it will end in usb_io()
and this is an asynchronous function to use somehow the USB IP core
API of the mcu... it's wrong to use a stack variable here because it
can be overwritten. I am sorry, I did not keep that in mind...

- Alex


^ permalink raw reply	[flat|nested] 84+ messages in thread

end of thread, other threads:[~2022-09-05 22:35 UTC | newest]

Thread overview: 84+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-01 14:30 [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Miquel Raynal
2022-07-01 14:30 ` [PATCH wpan-next 01/20] net: mac802154: Allow the creation of coordinator interfaces Miquel Raynal
2022-07-06  1:51   ` Alexander Aring
2022-08-19 17:11     ` Miquel Raynal
2022-08-23 12:33       ` Alexander Aring
2022-08-23 16:29         ` Miquel Raynal
2022-08-23 21:44           ` Alexander Aring
2022-08-24  7:35             ` Miquel Raynal
2022-08-24 21:43               ` Alexander Aring
2022-08-25  8:40                 ` Miquel Raynal
2022-08-26  0:51                   ` Alexander Aring
2022-08-26  1:35                     ` Alexander Aring
2022-08-26  8:08                       ` Miquel Raynal
2022-08-29  2:31                         ` Alexander Aring
2022-08-29  8:05                           ` Miquel Raynal
2022-08-26  7:30                     ` Miquel Raynal
2022-08-24 10:20             ` Miquel Raynal
2022-08-24 12:43               ` Alexander Aring
2022-08-24 13:26                 ` Miquel Raynal
2022-08-24 21:53                   ` Alexander Aring
2022-08-25  1:02                     ` Alexander Aring
2022-08-25  8:46                       ` Miquel Raynal
2022-08-25 12:58                     ` Miquel Raynal
2022-08-26  1:05                       ` Alexander Aring
2022-08-26  7:54                         ` Miquel Raynal
2022-08-29  2:52                           ` Alexander Aring
2022-08-29  8:02                             ` Miquel Raynal
2022-08-30  2:23                               ` Alexander Aring
2022-08-31 15:39                                 ` Miquel Raynal
2022-09-01  0:09                                   ` Miquel Raynal
2022-09-01 13:09                                     ` Miquel Raynal
2022-09-02  2:38                                       ` Alexander Aring
2022-09-03  0:08                                         ` Miquel Raynal
2022-09-03 14:20                                           ` Alexander Aring
2022-09-03 14:31                                             ` Alexander Aring
2022-09-03 16:05                                             ` Miquel Raynal
2022-09-03 18:21                                               ` Alexander Aring
2022-09-03 18:29                                                 ` Alexander Aring
2022-09-03 19:07                                               ` Alexander Aring
2022-09-03 19:10                                                 ` Alexander Aring
2022-09-03 19:40                                                   ` Alexander Aring
2022-09-05  3:16                                                     ` Miquel Raynal
2022-09-05 22:35                                                       ` Alexander Aring
2022-09-02  2:23                                     ` Alexander Aring
2022-09-02  2:39                                       ` Alexander Aring
2022-09-02  2:09                                   ` Alexander Aring
2022-07-01 14:30 ` [PATCH wpan-next 02/20] net: ieee802154: Advertize coordinators discovery Miquel Raynal
2022-07-01 14:30 ` [PATCH wpan-next 03/20] net: ieee802154: Handle " Miquel Raynal
2022-07-01 14:30 ` [PATCH wpan-next 04/20] net: ieee802154: Trace the registration of new PANs Miquel Raynal
2022-07-01 14:30 ` [PATCH wpan-next 05/20] net: ieee802154: Define frame types Miquel Raynal
2022-07-11  2:06   ` Alexander Aring
2022-08-19 17:13     ` Miquel Raynal
2022-07-01 14:30 ` [PATCH wpan-next 06/20] net: ieee802154: Add support for user scanning requests Miquel Raynal
2022-07-01 14:30 ` [PATCH wpan-next 07/20] net: ieee802154: Define a beacon frame header Miquel Raynal
2022-07-01 14:30 ` [PATCH wpan-next 08/20] net: mac802154: Prepare forcing specific symbol duration Miquel Raynal
2022-07-01 14:30 ` [PATCH wpan-next 09/20] net: mac802154: Introduce a global device lock Miquel Raynal
2022-07-04  1:12   ` Alexander Aring
2022-08-19 17:06     ` Miquel Raynal
2022-07-01 14:30 ` [PATCH wpan-next 10/20] net: mac802154: Handle passive scanning Miquel Raynal
2022-07-15  3:33   ` Alexander Aring
2022-07-15  3:42     ` Alexander Aring
2022-08-19 17:22       ` Miquel Raynal
2022-08-01 23:42     ` Alexander Aring
2022-08-01 23:54       ` Alexander Aring
2022-07-01 14:30 ` [PATCH wpan-next 11/20] net: ieee802154: Add support for user beaconing requests Miquel Raynal
2022-07-01 14:30 ` [PATCH wpan-next 12/20] net: mac802154: Handle basic beaconing Miquel Raynal
2022-07-01 14:30 ` [PATCH wpan-next 13/20] net: ieee802154: Add support for user active scan requests Miquel Raynal
2022-07-01 14:30 ` [PATCH wpan-next 14/20] net: mac802154: Handle active scanning Miquel Raynal
2022-07-01 14:30 ` [PATCH wpan-next 15/20] net: ieee802154: Add support for allowing to answer BEACON_REQ Miquel Raynal
2022-07-01 14:30 ` [PATCH wpan-next 16/20] net: mac802154: Handle received BEACON_REQ Miquel Raynal
2022-07-01 14:30 ` [PATCH wpan-next 17/20] net: ieee802154: Handle limited devices with only datagram support Miquel Raynal
2022-07-15  3:16   ` Alexander Aring
2022-08-19 17:13     ` Miquel Raynal
2022-08-23 12:43       ` Alexander Aring
2022-07-01 14:30 ` [PATCH wpan-next 18/20] ieee802154: ca8210: Flag the driver as being limited Miquel Raynal
2022-07-01 14:30 ` [PATCH wpan-next 19/20] ieee802154: hwsim: Do not check the rtnl Miquel Raynal
2022-07-06  1:23   ` Alexander Aring
2022-08-01 23:58     ` Alexander Aring
2022-08-19 17:09     ` Miquel Raynal
2022-08-25 22:41       ` Miquel Raynal
2022-07-01 14:30 ` [PATCH wpan-next 20/20] ieee802154: hwsim: Allow devices to be coordinators Miquel Raynal
2022-07-11  2:01   ` Alexander Aring
2022-08-19 17:12     ` Miquel Raynal
2022-07-04  1:17 ` [PATCH wpan-next 00/20] net: ieee802154: Support scanning/beaconing Alexander Aring

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).