Hi, On Wed, Nov 2, 2022 at 11:20 AM Miquel Raynal <miquel.raynal@xxxxxxxxxxx> wrote: > > 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 tell the user whether or not the beacon comes from a new device or > not, so stateless userspace applications might not spam the user with > identical information if not required. > > Co-developed-by: David Girault <david.girault@xxxxxxxxx> > Signed-off-by: David Girault <david.girault@xxxxxxxxx> > Signed-off-by: Miquel Raynal <miquel.raynal@xxxxxxxxxxx> > --- > include/net/cfg802154.h | 12 ++++ > net/ieee802154/Makefile | 2 +- > net/ieee802154/core.c | 2 + > net/ieee802154/nl802154.c | 2 + > net/ieee802154/pan.c | 114 ++++++++++++++++++++++++++++++++++++++ > 5 files changed, 131 insertions(+), 1 deletion(-) > create mode 100644 net/ieee802154/pan.c > > diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h > index 8d67d9ed438d..3057b4e0726c 100644 > --- a/include/net/cfg802154.h > +++ b/include/net/cfg802154.h > @@ -401,6 +401,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) > @@ -451,4 +455,12 @@ 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, gfp_t gfp); > +void cfg802154_free_coordinator_desc(struct ieee802154_coord_desc *desc); > +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 f6fb7a228747..b6bd04fe160b 100644 > --- a/net/ieee802154/nl802154.c > +++ b/net/ieee802154/nl802154.c > @@ -1368,6 +1368,8 @@ static int nl802154_advertise_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..0d4f752a090a > --- /dev/null > +++ b/net/ieee802154/pan.c > @@ -0,0 +1,114 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * IEEE 802.15.4 PAN management > + * > + * Copyright (C) 2021 Qorvo US, Inc > + * Authors: > + * - David Girault <david.girault@xxxxxxxxx> > + * - Miquel Raynal <miquel.raynal@xxxxxxxxxxx> > + */ > + > +#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, gfp_t gfp) > +{ > + struct ieee802154_coord_desc *desc; > + > + desc = kzalloc(sizeof(*desc), gfp); > + if (!desc) > + return ERR_PTR(-ENOMEM); > + > + desc->addr = kzalloc(sizeof(*coord), gfp); > + if (!desc->addr) { > + kfree(desc); > + return ERR_PTR(-ENOMEM); > + } > + > + memcpy(desc->addr, coord, sizeof(*coord)); > + > + return desc; > +} > +EXPORT_SYMBOL_GPL(cfg802154_alloc_coordinator); > + > +void cfg802154_free_coordinator_desc(struct ieee802154_coord_desc *desc) > +{ > + kfree(desc->addr); > + kfree(desc); > +} > +EXPORT_SYMBOL_GPL(cfg802154_free_coordinator_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; semantic is a little bit different, can we use "ieee802154_addr_equal()" here? - Alex