driverdev-devel.linuxdriverproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] staging: dpaa2-ethsw: various fixes
@ 2020-07-21  9:19 Ioana Ciornei
  2020-07-21  9:19 ` [PATCH 1/6] staging: dpaa2-ethsw: verify the nofifier block Ioana Ciornei
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Ioana Ciornei @ 2020-07-21  9:19 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-kernel, Ioana Ciornei

This patch set adds various fixes to the dpaa2-ethsw driver: checking
the received notifier block before acting on a switchdev notification,
destroying a workqueue after deregistering the notifiers, making sure
that new VLANs added have a place before actually adding them and other
problems like this.

I know this driver should be moved along from staging but we still have
the Rx/Tx functionality on switch ports and some general cleanup that we
are working towards. This is tackling the second part, no new feature
added here.

Ioana Ciornei (6):
  staging: dpaa2-ethsw: verify the nofifier block
  staging: dpaa2-ethsw: don't allow interfaces from different DPSWs to
    be bridged
  staging: dpaa2-ethsw: setup the STP state for all installed VLANs
  staging: dpaa2-ethsw: destroy workqueue after deregistering the
    notifiers
  staging: dpaa2-ethsw: read the port state from firmware
  staging: dpaa2-ethsw: check if there is space for a new VLAN

 drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 114 +++++++++++++++++++-----
 1 file changed, 90 insertions(+), 24 deletions(-)

-- 
2.25.1

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

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

* [PATCH 1/6] staging: dpaa2-ethsw: verify the nofifier block
  2020-07-21  9:19 [PATCH 0/6] staging: dpaa2-ethsw: various fixes Ioana Ciornei
@ 2020-07-21  9:19 ` Ioana Ciornei
  2020-07-21  9:19 ` [PATCH 2/6] staging: dpaa2-ethsw: don't allow interfaces from different DPSWs to be bridged Ioana Ciornei
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Ioana Ciornei @ 2020-07-21  9:19 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-kernel, Ioana Ciornei

Since now we have a notifier block for each DPSW instance probed, we
have to also check that the netdev is indeed connected to the notifier
received. Without this, we end up with the same switchdev callback being
executed multiple times (because it would be received by all notifier
blocks, not just the one intended to).
Also, move the function higher in the source file because it will be
used in later patches from multiple places.

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 31 ++++++++++++++++---------
 1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index 2fb75a7c9314..557a75115da8 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -749,6 +749,20 @@ static const struct net_device_ops ethsw_port_ops = {
 	.ndo_get_phys_port_name = port_get_phys_name,
 };
 
+static bool ethsw_port_dev_check(const struct net_device *netdev,
+				 struct notifier_block *nb)
+{
+	struct ethsw_port_priv *port_priv = netdev_priv(netdev);
+
+	if (netdev->netdev_ops == &ethsw_port_ops &&
+	    (!nb || &port_priv->ethsw_data->port_nb == nb ||
+	     &port_priv->ethsw_data->port_switchdev_nb == nb ||
+	     &port_priv->ethsw_data->port_switchdevb_nb == nb))
+		return true;
+
+	return false;
+}
+
 static void ethsw_links_state_update(struct ethsw_core *ethsw)
 {
 	int i;
@@ -1199,12 +1213,7 @@ static int port_bridge_leave(struct net_device *netdev)
 	return err;
 }
 
-static bool ethsw_port_dev_check(const struct net_device *netdev)
-{
-	return netdev->netdev_ops == &ethsw_port_ops;
-}
-
-static int port_netdevice_event(struct notifier_block *unused,
+static int port_netdevice_event(struct notifier_block *nb,
 				unsigned long event, void *ptr)
 {
 	struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
@@ -1212,7 +1221,7 @@ static int port_netdevice_event(struct notifier_block *unused,
 	struct net_device *upper_dev;
 	int err = 0;
 
-	if (!ethsw_port_dev_check(netdev))
+	if (!ethsw_port_dev_check(netdev, nb))
 		return NOTIFY_DONE;
 
 	/* Handle just upper dev link/unlink for the moment */
@@ -1280,7 +1289,7 @@ static void ethsw_switchdev_event_work(struct work_struct *work)
 }
 
 /* Called under rcu_read_lock() */
-static int port_switchdev_event(struct notifier_block *unused,
+static int port_switchdev_event(struct notifier_block *nb,
 				unsigned long event, void *ptr)
 {
 	struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
@@ -1289,7 +1298,7 @@ static int port_switchdev_event(struct notifier_block *unused,
 	struct switchdev_notifier_fdb_info *fdb_info = ptr;
 	struct ethsw_core *ethsw = port_priv->ethsw_data;
 
-	if (!ethsw_port_dev_check(dev))
+	if (!ethsw_port_dev_check(dev, nb))
 		return NOTIFY_DONE;
 
 	if (event == SWITCHDEV_PORT_ATTR_SET)
@@ -1353,12 +1362,12 @@ ethsw_switchdev_port_obj_event(unsigned long event, struct net_device *netdev,
 	return notifier_from_errno(err);
 }
 
-static int port_switchdev_blocking_event(struct notifier_block *unused,
+static int port_switchdev_blocking_event(struct notifier_block *nb,
 					 unsigned long event, void *ptr)
 {
 	struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
 
-	if (!ethsw_port_dev_check(dev))
+	if (!ethsw_port_dev_check(dev, nb))
 		return NOTIFY_DONE;
 
 	switch (event) {
-- 
2.25.1

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

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

* [PATCH 2/6] staging: dpaa2-ethsw: don't allow interfaces from different DPSWs to be bridged
  2020-07-21  9:19 [PATCH 0/6] staging: dpaa2-ethsw: various fixes Ioana Ciornei
  2020-07-21  9:19 ` [PATCH 1/6] staging: dpaa2-ethsw: verify the nofifier block Ioana Ciornei
@ 2020-07-21  9:19 ` Ioana Ciornei
  2020-07-21  9:19 ` [PATCH 3/6] staging: dpaa2-ethsw: setup the STP state for all installed VLANs Ioana Ciornei
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Ioana Ciornei @ 2020-07-21  9:19 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-kernel, Ioana Ciornei

Error out when the user tries to bridge two switch interfaces that are
from different DPSW instances. This is not supported by the hardware and
we should reflect this into what the user is aware of.

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index 557a75115da8..530e4105375c 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -1182,6 +1182,9 @@ static int port_bridge_join(struct net_device *netdev,
 {
 	struct ethsw_port_priv *port_priv = netdev_priv(netdev);
 	struct ethsw_core *ethsw = port_priv->ethsw_data;
+	struct ethsw_port_priv *other_port_priv;
+	struct net_device *other_dev;
+	struct list_head *iter;
 	int i, err;
 
 	for (i = 0; i < ethsw->sw_attr.num_ifs; i++)
@@ -1192,6 +1195,18 @@ static int port_bridge_join(struct net_device *netdev,
 			return -EINVAL;
 		}
 
+	netdev_for_each_lower_dev(upper_dev, other_dev, iter) {
+		if (!ethsw_port_dev_check(other_dev, NULL))
+			continue;
+
+		other_port_priv = netdev_priv(other_dev);
+		if (other_port_priv->ethsw_data != port_priv->ethsw_data) {
+			netdev_err(netdev,
+				   "Interface from a different DPSW is in the bridge already!\n");
+			return -EINVAL;
+		}
+	}
+
 	/* Enable flooding */
 	err = ethsw_port_set_flood(port_priv, 1);
 	if (!err)
-- 
2.25.1

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

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

* [PATCH 3/6] staging: dpaa2-ethsw: setup the STP state for all installed VLANs
  2020-07-21  9:19 [PATCH 0/6] staging: dpaa2-ethsw: various fixes Ioana Ciornei
  2020-07-21  9:19 ` [PATCH 1/6] staging: dpaa2-ethsw: verify the nofifier block Ioana Ciornei
  2020-07-21  9:19 ` [PATCH 2/6] staging: dpaa2-ethsw: don't allow interfaces from different DPSWs to be bridged Ioana Ciornei
@ 2020-07-21  9:19 ` Ioana Ciornei
  2020-07-21  9:19 ` [PATCH 4/6] staging: dpaa2-ethsw: destroy workqueue after deregistering the notifiers Ioana Ciornei
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Ioana Ciornei @ 2020-07-21  9:19 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-kernel, Ioana Ciornei

Setup the STP state for all VLANs installed on the port. This is also
avoiding the error situation when the DEFAULT_VLAN_ID is not installed
on the port (thus the firmware complains that it cannot setup the
required STP state).

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index 530e4105375c..83e6bd4a803b 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -183,21 +183,26 @@ static int ethsw_port_set_flood(struct ethsw_port_priv *port_priv, bool enable)
 static int ethsw_port_set_stp_state(struct ethsw_port_priv *port_priv, u8 state)
 {
 	struct dpsw_stp_cfg stp_cfg = {
-		.vlan_id = DEFAULT_VLAN_ID,
 		.state = state,
 	};
 	int err;
+	u16 vid;
 
 	if (!netif_running(port_priv->netdev) || state == port_priv->stp_state)
 		return 0;	/* Nothing to do */
 
-	err = dpsw_if_set_stp(port_priv->ethsw_data->mc_io, 0,
-			      port_priv->ethsw_data->dpsw_handle,
-			      port_priv->idx, &stp_cfg);
-	if (err) {
-		netdev_err(port_priv->netdev,
-			   "dpsw_if_set_stp err %d\n", err);
-		return err;
+	for (vid = 0; vid <= VLAN_VID_MASK; vid++) {
+		if (port_priv->vlans[vid] & ETHSW_VLAN_MEMBER) {
+			stp_cfg.vlan_id = vid;
+			err = dpsw_if_set_stp(port_priv->ethsw_data->mc_io, 0,
+					      port_priv->ethsw_data->dpsw_handle,
+					      port_priv->idx, &stp_cfg);
+			if (err) {
+				netdev_err(port_priv->netdev,
+					   "dpsw_if_set_stp err %d\n", err);
+				return err;
+			}
+		}
 	}
 
 	port_priv->stp_state = state;
-- 
2.25.1

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

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

* [PATCH 4/6] staging: dpaa2-ethsw: destroy workqueue after deregistering the notifiers
  2020-07-21  9:19 [PATCH 0/6] staging: dpaa2-ethsw: various fixes Ioana Ciornei
                   ` (2 preceding siblings ...)
  2020-07-21  9:19 ` [PATCH 3/6] staging: dpaa2-ethsw: setup the STP state for all installed VLANs Ioana Ciornei
@ 2020-07-21  9:19 ` Ioana Ciornei
  2020-07-21  9:19 ` [PATCH 5/6] staging: dpaa2-ethsw: read the port state from firmware Ioana Ciornei
  2020-07-21  9:19 ` [PATCH 6/6] staging: dpaa2-ethsw: check if there is space for a new VLAN Ioana Ciornei
  5 siblings, 0 replies; 7+ messages in thread
From: Ioana Ciornei @ 2020-07-21  9:19 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-kernel, Ioana Ciornei

We should destroy the switch workqueue only after deregistering the
switchdev notifiers. Without this fix, we could end up with switchdev
notifications on a draining workqueue and also with a lock up since the
netdevice reference count is increased (in port_switchdev_event) and not
decreased ever (since the workqueue did not run).

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index 83e6bd4a803b..9114437645a8 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -1628,8 +1628,6 @@ static int ethsw_remove(struct fsl_mc_device *sw_dev)
 
 	ethsw_teardown_irqs(sw_dev);
 
-	destroy_workqueue(ethsw->workqueue);
-
 	dpsw_disable(ethsw->mc_io, 0, ethsw->dpsw_handle);
 
 	for (i = 0; i < ethsw->sw_attr.num_ifs; i++) {
@@ -1640,6 +1638,9 @@ static int ethsw_remove(struct fsl_mc_device *sw_dev)
 	kfree(ethsw->ports);
 
 	ethsw_takedown(sw_dev);
+
+	destroy_workqueue(ethsw->workqueue);
+
 	fsl_mc_portal_free(ethsw->mc_io);
 
 	kfree(ethsw);
-- 
2.25.1

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

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

* [PATCH 5/6] staging: dpaa2-ethsw: read the port state from firmware
  2020-07-21  9:19 [PATCH 0/6] staging: dpaa2-ethsw: various fixes Ioana Ciornei
                   ` (3 preceding siblings ...)
  2020-07-21  9:19 ` [PATCH 4/6] staging: dpaa2-ethsw: destroy workqueue after deregistering the notifiers Ioana Ciornei
@ 2020-07-21  9:19 ` Ioana Ciornei
  2020-07-21  9:19 ` [PATCH 6/6] staging: dpaa2-ethsw: check if there is space for a new VLAN Ioana Ciornei
  5 siblings, 0 replies; 7+ messages in thread
From: Ioana Ciornei @ 2020-07-21  9:19 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-kernel, Ioana Ciornei

Rely on the port state seen by the firmware since it will also be the
one erroring out when trying to setup anything major when the port is
up.

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index 9114437645a8..c6885912c60b 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -43,6 +43,25 @@ static int ethsw_add_vlan(struct ethsw_core *ethsw, u16 vid)
 	return 0;
 }
 
+static bool ethsw_port_is_up(struct ethsw_port_priv *port_priv)
+{
+	struct net_device *netdev = port_priv->netdev;
+	struct dpsw_link_state state;
+	int err;
+
+	err = dpsw_if_get_link_state(port_priv->ethsw_data->mc_io, 0,
+				     port_priv->ethsw_data->dpsw_handle,
+				     port_priv->idx, &state);
+	if (err) {
+		netdev_err(netdev, "dpsw_if_get_link_state() err %d\n", err);
+		return true;
+	}
+
+	WARN_ONCE(state.up > 1, "Garbage read into link_state");
+
+	return state.up ? true : false;
+}
+
 static int ethsw_port_set_pvid(struct ethsw_port_priv *port_priv, u16 pvid)
 {
 	struct ethsw_core *ethsw = port_priv->ethsw_data;
@@ -61,7 +80,7 @@ static int ethsw_port_set_pvid(struct ethsw_port_priv *port_priv, u16 pvid)
 	tci_cfg.vlan_id = pvid;
 
 	/* Interface needs to be down to change PVID */
-	up = netif_running(netdev);
+	up = ethsw_port_is_up(port_priv);
 	if (up) {
 		err = dpsw_if_disable(ethsw->mc_io, 0,
 				      ethsw->dpsw_handle,
-- 
2.25.1

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

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

* [PATCH 6/6] staging: dpaa2-ethsw: check if there is space for a new VLAN
  2020-07-21  9:19 [PATCH 0/6] staging: dpaa2-ethsw: various fixes Ioana Ciornei
                   ` (4 preceding siblings ...)
  2020-07-21  9:19 ` [PATCH 5/6] staging: dpaa2-ethsw: read the port state from firmware Ioana Ciornei
@ 2020-07-21  9:19 ` Ioana Ciornei
  5 siblings, 0 replies; 7+ messages in thread
From: Ioana Ciornei @ 2020-07-21  9:19 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-kernel, Ioana Ciornei

Avoid getting into a WARNING as below by checking, while in the prepare
state of the transactional operation, if there is space for a new VLAN.
If we reached the maximum number, return an appropriate error.

[ 6503.657564] eth3: Commit of object (id=1) failed.
[ 6503.657588] WARNING: CPU: 2 PID: 17144 at net/switchdev/switchdev.c:277 switchdev_port_obj_add_now+0xcc/0x110
...
[ 6503.657628] x1 : 70887ce26695c500 x0 : 0000000000000000
[ 6503.657630] Call trace:
[ 6503.657633]  switchdev_port_obj_add_now+0xcc/0x110
[ 6503.657635]  switchdev_port_obj_add+0x40/0xc0
[ 6503.657638]  br_switchdev_port_vlan_add+0x50/0x78
[ 6503.657640]  __vlan_add+0x2dc/0x758
[ 6503.657642]  nbp_vlan_add+0xc0/0x180
[ 6503.657644]  br_vlan_info.isra.0+0x68/0x128
[ 6503.657646]  br_process_vlan_info+0x224/0x2f8
[ 6503.657647]  br_afspec+0x158/0x188
[ 6503.657649]  br_setlink+0x1a4/0x290

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index c6885912c60b..19fc0401e261 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -979,10 +979,27 @@ static int port_vlans_add(struct net_device *netdev,
 			  struct switchdev_trans *trans)
 {
 	struct ethsw_port_priv *port_priv = netdev_priv(netdev);
-	int vid, err = 0;
+	struct ethsw_core *ethsw = port_priv->ethsw_data;
+	struct dpsw_attr *attr = &ethsw->sw_attr;
+	int vid, err = 0, new_vlans = 0;
+
+	if (switchdev_trans_ph_prepare(trans)) {
+		for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++)
+			if (!port_priv->ethsw_data->vlans[vid])
+				new_vlans++;
+
+		/* Check if there is space for a new VLAN */
+		err = dpsw_get_attributes(ethsw->mc_io, 0, ethsw->dpsw_handle,
+					  &ethsw->sw_attr);
+		if (err) {
+			netdev_err(netdev, "dpsw_get_attributes err %d\n", err);
+			return err;
+		}
+		if (attr->max_vlans - attr->num_vlans < new_vlans)
+			return -ENOSPC;
 
-	if (switchdev_trans_ph_prepare(trans))
 		return 0;
+	}
 
 	for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {
 		if (!port_priv->ethsw_data->vlans[vid]) {
-- 
2.25.1

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

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

end of thread, other threads:[~2020-07-21  9:19 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-21  9:19 [PATCH 0/6] staging: dpaa2-ethsw: various fixes Ioana Ciornei
2020-07-21  9:19 ` [PATCH 1/6] staging: dpaa2-ethsw: verify the nofifier block Ioana Ciornei
2020-07-21  9:19 ` [PATCH 2/6] staging: dpaa2-ethsw: don't allow interfaces from different DPSWs to be bridged Ioana Ciornei
2020-07-21  9:19 ` [PATCH 3/6] staging: dpaa2-ethsw: setup the STP state for all installed VLANs Ioana Ciornei
2020-07-21  9:19 ` [PATCH 4/6] staging: dpaa2-ethsw: destroy workqueue after deregistering the notifiers Ioana Ciornei
2020-07-21  9:19 ` [PATCH 5/6] staging: dpaa2-ethsw: read the port state from firmware Ioana Ciornei
2020-07-21  9:19 ` [PATCH 6/6] staging: dpaa2-ethsw: check if there is space for a new VLAN Ioana Ciornei

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).