From: Yuying Zhang <yuying.zhang@intel.com>
To: dev@dpdk.org, qi.z.zhang@intel.com, jingjing.wu@intel.com,
beilei.xing@intel.com
Cc: Yuying Zhang <yuying.zhang@intel.com>
Subject: [PATCH v2 8/8] net/cpfl: add flow support for representor
Date: Fri, 1 Sep 2023 11:31:58 +0000 [thread overview]
Message-ID: <20230901113158.1654044-9-yuying.zhang@intel.com> (raw)
In-Reply-To: <20230901113158.1654044-1-yuying.zhang@intel.com>
Add flow support for representor, so representor can
create, destroy, validate and flush rules.
Signed-off-by: Yuying Zhang <yuying.zhang@intel.com>
---
doc/guides/nics/cpfl.rst | 13 +++++++++++
doc/guides/rel_notes/release_23_11.rst | 1 +
drivers/net/cpfl/cpfl_flow_engine_fxp.c | 24 ++++++++++++++++++--
drivers/net/cpfl/cpfl_representor.c | 29 +++++++++++++++++++++++++
4 files changed, 65 insertions(+), 2 deletions(-)
diff --git a/doc/guides/nics/cpfl.rst b/doc/guides/nics/cpfl.rst
index 7032dd1a1a..e2fe5430ed 100644
--- a/doc/guides/nics/cpfl.rst
+++ b/doc/guides/nics/cpfl.rst
@@ -196,3 +196,16 @@ low level hardware resources defined in a DDP package file.
.. code-block:: console
dpdk-testpmd -c 0x3 -n 4 -a 0000:af:00.6,vport=[0],flow_parser="refpkg.json" -- -i
+
+#. Create one flow to forward ETH-IPV4-TCP from I/O port to a local(CPF's) vport::
+
+ .. code-block:: console
+
+ flow create 0 ingress group 1 pattern eth dst is 00:01:00:00:03:14 / ipv4 src is 192.168.0.1 \
+ dst is 192.168.0.2 / tcp / end actions port_representor port_id 0 / end
+
+#. Send the packet, and it should be displayed on PMD::
+
+ .. code-block:: console
+
+ sendp(Ether(dst='00:01:00:00:03:14')/IP(src='192.168.0.1',dst='192.168.0.2')/TCP(),iface="enp24s0f0")
diff --git a/doc/guides/rel_notes/release_23_11.rst b/doc/guides/rel_notes/release_23_11.rst
index 688bee4d6d..eded3ecc84 100644
--- a/doc/guides/rel_notes/release_23_11.rst
+++ b/doc/guides/rel_notes/release_23_11.rst
@@ -58,6 +58,7 @@ New Features
* **Updated Intel cpfl driver.**
* Added support for port representor.
+ * Added support for rte_flow.
Removed Items
-------------
diff --git a/drivers/net/cpfl/cpfl_flow_engine_fxp.c b/drivers/net/cpfl/cpfl_flow_engine_fxp.c
index e0c08a77c3..f40402a912 100644
--- a/drivers/net/cpfl/cpfl_flow_engine_fxp.c
+++ b/drivers/net/cpfl/cpfl_flow_engine_fxp.c
@@ -73,6 +73,7 @@ cpfl_fxp_create(struct rte_eth_dev *dev,
struct cpfl_adapter_ext *ad = itf->adapter;
struct cpfl_rule_info_meta *rim = meta;
struct cpfl_vport *vport;
+ struct cpfl_repr *repr;
if (!rim)
return ret;
@@ -83,6 +84,10 @@ cpfl_fxp_create(struct rte_eth_dev *dev,
* Even index is tx queue and odd index is rx queue.
*/
cpq_id = vport->base.devarg_id * 2;
+ } else if (itf->type == CPFL_ITF_TYPE_REPRESENTOR) {
+ repr = (struct cpfl_repr *)itf;
+ cpq_id = ((repr->repr_id.pf_id + repr->repr_id.vf_id) &
+ (CPFL_TX_CFGQ_NUM - 1)) * 2;
} else {
rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
"fail to find correct control queue");
@@ -122,6 +127,7 @@ cpfl_fxp_destroy(struct rte_eth_dev *dev,
struct cpfl_rule_info_meta *rim;
uint32_t i;
struct cpfl_vport *vport;
+ struct cpfl_repr *repr;
rim = flow->rule;
if (!rim) {
@@ -135,6 +141,10 @@ cpfl_fxp_destroy(struct rte_eth_dev *dev,
if (itf->type == CPFL_ITF_TYPE_VPORT) {
vport = (struct cpfl_vport *)itf;
cpq_id = vport->base.devarg_id * 2;
+ } else if (itf->type == CPFL_ITF_TYPE_REPRESENTOR) {
+ repr = (struct cpfl_repr *)itf;
+ cpq_id = ((repr->repr_id.pf_id + repr->repr_id.vf_id) &
+ (CPFL_TX_CFGQ_NUM - 1)) * 2;
} else {
rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
"fail to find correct control queue");
@@ -257,6 +267,7 @@ cpfl_fxp_parse_action(struct cpfl_itf *itf,
int queue_id = -1;
bool fwd_vsi = false;
bool fwd_q = false;
+ bool is_vsi;
uint32_t i;
struct cpfl_rule_info *rinfo = &rim->rules[index];
union cpfl_action_set *act_set = (void *)rinfo->act_bytes;
@@ -267,6 +278,7 @@ cpfl_fxp_parse_action(struct cpfl_itf *itf,
action_type = action->type;
switch (action_type) {
case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
+ case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
if (!fwd_vsi)
fwd_vsi = true;
else
@@ -285,12 +297,20 @@ cpfl_fxp_parse_action(struct cpfl_itf *itf,
queue_id = CPFL_INVALID_QUEUE_ID;
}
- dev_id = cpfl_get_vsi_id(dst_itf);
+ is_vsi = (action_type == RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR ||
+ dst_itf->type == CPFL_ITF_TYPE_REPRESENTOR);
+ if (is_vsi)
+ dev_id = cpfl_get_vsi_id(dst_itf);
+ else
+ dev_id = cpfl_get_port_id(dst_itf);
if (dev_id == CPFL_INVALID_HW_ID)
goto err;
- *act_set = cpfl_act_fwd_vsi(0, priority, 0, dev_id);
+ if (is_vsi)
+ *act_set = cpfl_act_fwd_vsi(0, priority, 0, dev_id);
+ else
+ *act_set = cpfl_act_fwd_port(0, priority, 0, dev_id);
act_set++;
rinfo->act_byte_len += sizeof(union cpfl_action_set);
break;
diff --git a/drivers/net/cpfl/cpfl_representor.c b/drivers/net/cpfl/cpfl_representor.c
index 83069d0830..6e7d3fd0a6 100644
--- a/drivers/net/cpfl/cpfl_representor.c
+++ b/drivers/net/cpfl/cpfl_representor.c
@@ -4,6 +4,8 @@
#include "cpfl_representor.h"
#include "cpfl_rxtx.h"
+#include "cpfl_flow.h"
+#include "cpfl_rules.h"
static int
cpfl_repr_whitelist_update(struct cpfl_adapter_ext *adapter,
@@ -325,6 +327,22 @@ cpfl_repr_link_update(struct rte_eth_dev *ethdev,
return 0;
}
+static int
+cpfl_dev_repr_flow_ops_get(struct rte_eth_dev *dev,
+ const struct rte_flow_ops **ops)
+{
+ if (!dev)
+ return -EINVAL;
+
+#ifdef CPFL_FLOW_JSON_SUPPORT
+ *ops = &cpfl_flow_ops;
+#else
+ *ops = NULL;
+ PMD_DRV_LOG(NOTICE, "not support rte_flow, please install json-c library.");
+#endif
+ return 0;
+}
+
static const struct eth_dev_ops cpfl_repr_dev_ops = {
.dev_start = cpfl_repr_dev_start,
.dev_stop = cpfl_repr_dev_stop,
@@ -336,6 +354,7 @@ static const struct eth_dev_ops cpfl_repr_dev_ops = {
.tx_queue_setup = idpf_repr_tx_queue_setup,
.link_update = cpfl_repr_link_update,
+ .flow_ops_get = cpfl_dev_repr_flow_ops_get,
};
static int
@@ -344,6 +363,7 @@ cpfl_repr_init(struct rte_eth_dev *eth_dev, void *init_param)
struct cpfl_repr *repr = CPFL_DEV_TO_REPR(eth_dev);
struct cpfl_repr_param *param = init_param;
struct cpfl_adapter_ext *adapter = param->adapter;
+ int ret;
repr->repr_id = param->repr_id;
repr->vport_info = param->vport_info;
@@ -353,6 +373,15 @@ cpfl_repr_init(struct rte_eth_dev *eth_dev, void *init_param)
if (repr->vport_info->vport_info.vport_status == CPCHNL2_VPORT_STATUS_ENABLED)
repr->func_up = true;
+ TAILQ_INIT(&repr->itf.flow_list);
+ memset(repr->itf.dma, 0, sizeof(repr->itf.dma));
+ memset(repr->itf.msg, 0, sizeof(repr->itf.msg));
+ ret = cpfl_alloc_dma_mem_batch(&repr->itf.flow_dma, repr->itf.dma,
+ sizeof(union cpfl_rule_cfg_pkt_record),
+ CPFL_FLOW_BATCH_SIZE);
+ if (ret < 0)
+ return ret;
+
eth_dev->dev_ops = &cpfl_repr_dev_ops;
eth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;
--
2.25.1
next prev parent reply other threads:[~2023-09-01 11:10 UTC|newest]
Thread overview: 128+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-12 7:55 [PATCH v1 0/5] add rte flow support for cpfl Yuying Zhang
2023-08-12 7:55 ` [PATCH v1 1/5] net/cpfl: setup rte flow skeleton Yuying Zhang
2023-08-25 3:55 ` Xing, Beilei
2023-08-12 7:55 ` [PATCH v1 2/5] common/idpf/base: refine idpf ctlq message structure Yuying Zhang
2023-08-25 5:55 ` Xing, Beilei
2023-08-12 7:55 ` [PATCH v1 3/5] net/cpfl: add cpfl control queue message handle Yuying Zhang
2023-08-25 6:23 ` Xing, Beilei
2023-08-12 7:55 ` [PATCH v1 4/5] net/cpfl: add fxp rule module Yuying Zhang
2023-08-25 7:35 ` Xing, Beilei
2023-08-25 8:42 ` Xing, Beilei
2023-08-12 7:55 ` [PATCH v1 5/5] net/cpfl: add fxp flow engine Yuying Zhang
2023-08-25 9:15 ` Xing, Beilei
2023-09-01 11:31 ` [PATCH v2 0/8] add rte flow support for cpfl Yuying Zhang
2023-09-01 11:31 ` [PATCH v2 1/8] net/cpfl: parse flow parser file in devargs Yuying Zhang
2023-09-01 11:31 ` [PATCH v2 2/8] net/cpfl: add flow json parser Yuying Zhang
2023-09-01 11:31 ` [PATCH v2 3/8] net/cpfl: add FXP low level implementation Yuying Zhang
2023-09-01 11:31 ` [PATCH v2 4/8] net/cpfl: setup ctrl path Yuying Zhang
2023-09-01 11:31 ` [PATCH v2 5/8] net/cpfl: set up rte flow skeleton Yuying Zhang
2023-09-01 11:31 ` [PATCH v2 6/8] net/cpfl: add fxp rule module Yuying Zhang
2023-09-01 11:31 ` [PATCH v2 7/8] net/cpfl: add fxp flow engine Yuying Zhang
2023-09-01 11:31 ` Yuying Zhang [this message]
2023-09-06 9:33 ` [PATCH v3 0/9] add rte flow support for cpfl Wenjing Qiao
2023-08-15 16:50 ` [PATCH v4 " Zhang, Yuying
2023-08-15 16:50 ` [PATCH v4 1/9] net/cpfl: add json parser for rte flow pattern rules Zhang, Yuying
2023-09-15 15:11 ` Stephen Hemminger
2023-08-15 16:50 ` [PATCH v4 2/9] net/cpfl: add mod rule parser support for rte flow Zhang, Yuying
2023-08-15 16:50 ` [PATCH v4 3/9] net/cpfl: set up rte flow skeleton Zhang, Yuying
2023-08-15 16:50 ` [PATCH v4 4/9] net/cpfl: add FXP low level implementation Zhang, Yuying
2023-08-15 16:50 ` [PATCH v4 5/9] net/cpfl: add fxp rule module Zhang, Yuying
2023-08-15 16:50 ` [PATCH v4 6/9] net/cpfl: add fxp flow engine Zhang, Yuying
2023-08-15 16:50 ` [PATCH v4 7/9] net/cpfl: add flow support for representor Zhang, Yuying
2023-08-15 16:50 ` [PATCH v4 8/9] app/test-pmd: refine encap content Zhang, Yuying
2023-08-15 16:50 ` [PATCH v4 9/9] net/cpfl: fix incorrect status calculation Zhang, Yuying
2023-09-06 9:33 ` [PATCH v3 1/9] net/cpfl: parse flow parser file in devargs Wenjing Qiao
2023-09-11 0:48 ` Wu, Jingjing
2023-09-06 9:34 ` [PATCH v3 2/9] net/cpfl: add flow json parser Wenjing Qiao
2023-09-08 6:26 ` Liu, Mingxia
2023-09-11 6:24 ` Wu, Jingjing
2023-09-06 9:34 ` [PATCH v3 3/9] net/cpfl: add FXP low level implementation Wenjing Qiao
2023-09-06 9:34 ` [PATCH v3 4/9] net/cpfl: setup ctrl path Wenjing Qiao
2023-09-11 6:30 ` Liu, Mingxia
2023-09-11 6:36 ` Wu, Jingjing
2023-09-06 9:34 ` [PATCH v3 5/9] net/cpfl: set up rte flow skeleton Wenjing Qiao
2023-09-06 9:34 ` [PATCH v3 6/9] net/cpfl: add fxp rule module Wenjing Qiao
2023-09-12 7:40 ` FW: " Liu, Mingxia
2023-09-06 9:34 ` [PATCH v3 7/9] net/cpfl: add fxp flow engine Wenjing Qiao
2023-09-06 9:34 ` [PATCH v3 8/9] net/cpfl: add flow support for representor Wenjing Qiao
2023-09-06 9:34 ` [PATCH v3 9/9] app/test-pmd: refine encap content Wenjing Qiao
2023-09-15 10:00 ` [PATCH v5 0/9] add rte flow support for cpfl Zhang, Yuying
2023-08-22 1:02 ` [PATCH v6 0/8] " Zhang, Yuying
2023-08-22 1:02 ` [PATCH v6 1/8] net/cpfl: add json parser for rte flow pattern rules Zhang, Yuying
2023-08-22 1:02 ` [PATCH v6 2/8] net/cpfl: add mod rule parser support for rte flow Zhang, Yuying
2023-08-22 1:02 ` [PATCH v6 3/8] net/cpfl: set up rte flow skeleton Zhang, Yuying
2023-08-22 1:02 ` [PATCH v6 4/8] net/cpfl: set up control path Zhang, Yuying
2023-08-22 1:02 ` [PATCH v6 5/8] net/cpfl: add FXP low level implementation Zhang, Yuying
2023-08-22 1:02 ` [PATCH v6 6/8] net/cpfl: add fxp rule module Zhang, Yuying
2023-08-22 1:02 ` [PATCH v6 7/8] net/cpfl: add fxp flow engine Zhang, Yuying
2023-08-22 1:02 ` [PATCH v6 8/8] net/cpfl: add flow support for representor Zhang, Yuying
2023-09-26 18:16 ` [PATCH v7 0/8] add rte flow support for cpfl yuying.zhang
2023-09-26 18:16 ` [PATCH v7 1/8] net/cpfl: add json parser for rte flow pattern rules yuying.zhang
2023-09-26 19:03 ` Stephen Hemminger
2023-09-27 1:21 ` Zhang, Qi Z
2023-09-26 18:16 ` [PATCH v7 2/8] net/cpfl: build action mapping rules from JSON yuying.zhang
2023-09-26 18:16 ` [PATCH v7 3/8] net/cpfl: set up rte flow skeleton yuying.zhang
2023-09-26 18:16 ` [PATCH v7 4/8] net/cpfl: set up control path yuying.zhang
2023-09-26 18:17 ` [PATCH v7 5/8] net/cpfl: add FXP low level implementation yuying.zhang
2023-09-26 18:17 ` [PATCH v7 6/8] net/cpfl: add fxp rule module yuying.zhang
2023-09-28 3:29 ` Zhang, Qi Z
2023-09-26 18:17 ` [PATCH v7 7/8] net/cpfl: add fxp flow engine yuying.zhang
2023-09-26 18:17 ` [PATCH v7 8/8] net/cpfl: add flow support for representor yuying.zhang
2023-09-27 12:54 ` [PATCH v8 0/9] add rte flow support for cpfl yuying.zhang
2023-09-27 12:54 ` [PATCH v8 1/9] net/cpfl: add json parser for rte flow pattern rules yuying.zhang
2023-09-27 12:54 ` [PATCH v8 2/9] net/cpfl: build action mapping rules from JSON yuying.zhang
2023-09-27 12:54 ` [PATCH v8 3/9] net/cpfl: set up rte flow skeleton yuying.zhang
2023-09-27 12:54 ` [PATCH v8 4/9] net/cpfl: set up control path yuying.zhang
2023-09-27 12:54 ` [PATCH v8 5/9] net/cpfl: add FXP low level implementation yuying.zhang
2023-09-27 12:54 ` [PATCH v8 6/9] net/cpfl: add fxp rule module yuying.zhang
2023-09-27 12:54 ` [PATCH v8 7/9] net/cpfl: add fxp flow engine yuying.zhang
2023-09-27 12:54 ` [PATCH v8 8/9] net/cpfl: add flow support for representor yuying.zhang
2023-09-27 12:54 ` [PATCH v8 9/9] net/cpfl: add support of to represented port action yuying.zhang
2023-09-28 3:37 ` [PATCH v8 0/9] add rte flow support for cpfl Zhang, Qi Z
2023-09-28 8:44 ` [PATCH v9 " yuying.zhang
2023-09-08 16:05 ` [PATCH v10 " Zhang, Yuying
2023-09-08 16:05 ` [PATCH v10 1/9] net/cpfl: parse flow offloading hint from JSON Zhang, Yuying
2023-09-08 16:05 ` [PATCH v10 2/9] net/cpfl: build action mapping rules " Zhang, Yuying
2023-09-08 16:05 ` [PATCH v10 3/9] net/cpfl: set up flow offloading skeleton Zhang, Yuying
2023-09-08 16:05 ` [PATCH v10 4/9] net/cpfl: set up control path Zhang, Yuying
2023-09-08 16:05 ` [PATCH v10 5/9] net/cpfl: add FXP low level implementation Zhang, Yuying
2023-09-08 16:05 ` [PATCH v10 6/9] net/cpfl: implement FXP rule creation and destroying Zhang, Yuying
2023-09-08 16:05 ` [PATCH v10 7/9] net/cpfl: adapt FXP to flow engine Zhang, Yuying
2023-09-08 16:05 ` [PATCH v10 8/9] net/cpfl: support flow ops on representor Zhang, Yuying
2023-09-08 16:05 ` [PATCH v10 9/9] net/cpfl: support represented port action Zhang, Yuying
2023-09-28 8:44 ` [PATCH v9 1/9] net/cpfl: add json parser for rte flow pattern rules yuying.zhang
2023-09-28 8:44 ` [PATCH v9 2/9] net/cpfl: build action mapping rules from JSON yuying.zhang
2023-09-28 8:44 ` [PATCH v9 3/9] net/cpfl: set up rte flow skeleton yuying.zhang
2023-10-15 13:01 ` Thomas Monjalon
2023-10-16 3:07 ` Zhang, Qi Z
2023-09-28 8:44 ` [PATCH v9 4/9] net/cpfl: set up control path yuying.zhang
2023-09-28 8:44 ` [PATCH v9 5/9] net/cpfl: add FXP low level implementation yuying.zhang
2023-09-28 8:44 ` [PATCH v9 6/9] net/cpfl: add fxp rule module yuying.zhang
2023-09-28 8:44 ` [PATCH v9 7/9] net/cpfl: add fxp flow engine yuying.zhang
2023-09-28 8:44 ` [PATCH v9 8/9] net/cpfl: add flow support for representor yuying.zhang
2023-09-28 8:44 ` [PATCH v9 9/9] net/cpfl: add support of to represented port action yuying.zhang
2023-09-28 12:45 ` [PATCH v9 0/9] add rte flow support for cpfl Zhang, Qi Z
2023-09-28 16:04 ` Stephen Hemminger
2023-10-09 4:00 ` [PATCH v10 " Zhang, Yuying
2023-10-09 4:00 ` [PATCH v10 1/9] net/cpfl: parse flow offloading hint from JSON Zhang, Yuying
2023-10-09 4:00 ` [PATCH v10 2/9] net/cpfl: build action mapping rules " Zhang, Yuying
2023-10-09 4:00 ` [PATCH v10 3/9] net/cpfl: set up flow offloading skeleton Zhang, Yuying
2023-10-09 4:00 ` [PATCH v10 4/9] net/cpfl: set up control path Zhang, Yuying
2023-10-09 4:00 ` [PATCH v10 5/9] net/cpfl: add FXP low level implementation Zhang, Yuying
2023-10-09 4:00 ` [PATCH v10 6/9] net/cpfl: implement FXP rule creation and destroying Zhang, Yuying
2023-10-09 4:00 ` [PATCH v10 7/9] net/cpfl: adapt FXP to flow engine Zhang, Yuying
2023-10-09 4:00 ` [PATCH v10 8/9] net/cpfl: support flow ops on representor Zhang, Yuying
2023-10-09 4:00 ` [PATCH v10 9/9] net/cpfl: support represented port action Zhang, Yuying
2023-10-10 1:31 ` [PATCH v10 0/9] add rte flow support for cpfl Zhang, Qi Z
2023-10-15 11:21 ` [PATCH v9 " Thomas Monjalon
2023-09-15 10:00 ` [PATCH v5 1/9] net/cpfl: add json parser for rte flow pattern rules Zhang, Yuying
2023-09-15 11:14 ` Zhang, Qi Z
2023-09-15 10:00 ` [PATCH v5 2/9] net/cpfl: add mod rule parser support for rte flow Zhang, Yuying
2023-09-15 10:00 ` [PATCH v5 3/9] net/cpfl: set up rte flow skeleton Zhang, Yuying
2023-09-15 10:00 ` [PATCH v5 4/9] net/cpfl: add FXP low level implementation Zhang, Yuying
2023-09-15 11:19 ` Zhang, Qi Z
2023-09-15 10:00 ` [PATCH v5 5/9] net/cpfl: add fxp rule module Zhang, Yuying
2023-09-15 10:00 ` [PATCH v5 6/9] net/cpfl: add fxp flow engine Zhang, Yuying
2023-09-15 10:00 ` [PATCH v5 7/9] net/cpfl: add flow support for representor Zhang, Yuying
2023-09-15 10:00 ` [PATCH v5 8/9] app/test-pmd: refine encap content Zhang, Yuying
2023-09-15 10:00 ` [PATCH v5 9/9] net/cpfl: fix incorrect status calculation Zhang, Yuying
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230901113158.1654044-9-yuying.zhang@intel.com \
--to=yuying.zhang@intel.com \
--cc=beilei.xing@intel.com \
--cc=dev@dpdk.org \
--cc=jingjing.wu@intel.com \
--cc=qi.z.zhang@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).