* [dpdk-dev] [PATCH 1/5] ethdev: add multicast address filtering
2015-05-28 15:05 [dpdk-dev] [PATCH 0/5] multicast address filtering Ivan Boule
@ 2015-05-28 15:05 ` Ivan Boule
2015-05-28 16:22 ` Stephen Hemminger
2015-05-28 15:05 ` [dpdk-dev] [PATCH 2/5] app/testpmd: new command to add/remove multicast MAC addresses Ivan Boule
` (5 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Ivan Boule @ 2015-05-28 15:05 UTC (permalink / raw)
To: dev
With the current PMD API, the receipt of multicast packets on a given
port can only be enabled by invoking the "rte_eth_allmulticast_enable"
function.
This method may not work on Virtual Functions in SR-IOV architectures
when the host PF driver does not allow such operation on VFs.
In such cases, joined multicast addresses must be individually added
in the set of multicast addresses that are filtered by the [VF] port.
For this purpose, a new function "set_mc_addr_list" is introduced
into the set of functions that are exported by a Poll Mode Driver.
Signed-off-by: Ivan Boule <ivan.boule@6wind.com>
---
lib/librte_ether/rte_ethdev.c | 17 +++++++++++++++++
lib/librte_ether/rte_ethdev.h | 26 ++++++++++++++++++++++++++
2 files changed, 43 insertions(+)
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 024fe8b..f5784de 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3628,3 +3628,20 @@ rte_eth_remove_tx_callback(uint8_t port_id, uint16_t queue_id,
/* Callback wasn't found. */
return -EINVAL;
}
+
+int
+rte_eth_dev_set_mc_addr_list(uint8_t port_id,
+ struct ether_addr *mc_addr_set,
+ uint32_t nb_mc_addr)
+{
+ struct rte_eth_dev *dev;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return -ENODEV;
+ }
+
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_mc_addr_list, -ENOTSUP);
+ return dev->dev_ops->set_mc_addr_list(dev, mc_addr_set, nb_mc_addr);
+}
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 16dbe00..04c192d 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1228,6 +1228,10 @@ typedef int (*eth_udp_tunnel_del_t)(struct rte_eth_dev *dev,
struct rte_eth_udp_tunnel *tunnel_udp);
/**< @internal Delete tunneling UDP info */
+typedef int (*eth_set_mc_addr_list_t)(struct rte_eth_dev *dev,
+ struct ether_addr *mc_addr_set,
+ uint32_t nb_mc_addr);
+/**< @internal set the list of multicast addresses on an Ethernet device */
#ifdef RTE_NIC_BYPASS
@@ -1386,6 +1390,7 @@ struct eth_dev_ops {
/** Get current RSS hash configuration. */
rss_hash_conf_get_t rss_hash_conf_get;
eth_filter_ctrl_t filter_ctrl; /**< common filter control*/
+ eth_set_mc_addr_list_t set_mc_addr_list; /**< set list of mcast addrs */
};
/**
@@ -3615,4 +3620,25 @@ int rte_eth_remove_tx_callback(uint8_t port_id, uint16_t queue_id,
}
#endif
+/**
+ * Set the list of multicast addresses to filter on an Ethernet device.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param mc_addr_set
+ * The array of multicast addresses to set. Equal to NULL when the function
+ * is invoked to flush the set of filtered addresses.
+ * @param nb_mc_addr
+ * The number of multicast addresses in the *mc_addr_set* array. Equal to 0
+ * when the function is invoked to flush the set of filtered addresses.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-ENOTSUP) if PMD of *port_id* doesn't support multicast filtering.
+ * - (-ENOSPC) if *port_id* has not enough multicast filtering resources.
+ */
+int rte_eth_dev_set_mc_addr_list(uint8_t port_id,
+ struct ether_addr *mc_addr_set,
+ uint32_t nb_mc_addr);
+
#endif /* _RTE_ETHDEV_H_ */
--
1.7.10.4
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [dpdk-dev] [PATCH 1/5] ethdev: add multicast address filtering
2015-05-28 15:05 ` [dpdk-dev] [PATCH 1/5] ethdev: add " Ivan Boule
@ 2015-05-28 16:22 ` Stephen Hemminger
2015-05-29 7:52 ` Ivan Boule
` (2 more replies)
0 siblings, 3 replies; 15+ messages in thread
From: Stephen Hemminger @ 2015-05-28 16:22 UTC (permalink / raw)
To: Ivan Boule; +Cc: dev
On Thu, 28 May 2015 17:05:19 +0200
Ivan Boule <ivan.boule@6wind.com> wrote:
> + if (port_id >= nb_ports) {
> + PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
> + return -ENODEV;
> + }
> +
Use rte_eth_dev_is_valid_port() function instead.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [dpdk-dev] [PATCH 1/5] ethdev: add multicast address filtering
2015-05-28 16:22 ` Stephen Hemminger
@ 2015-05-29 7:52 ` Ivan Boule
2015-05-29 8:56 ` [dpdk-dev] [PATCH v2 " Ivan Boule
2015-05-29 13:12 ` [dpdk-dev] default unicast mac address - was: " Thomas Monjalon
2 siblings, 0 replies; 15+ messages in thread
From: Ivan Boule @ 2015-05-29 7:52 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
On 05/28/2015 06:22 PM, Stephen Hemminger wrote:
> On Thu, 28 May 2015 17:05:19 +0200
> Ivan Boule <ivan.boule@6wind.com> wrote:
>
>> + if (port_id >= nb_ports) {
>> + PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
>> + return -ENODEV;
>> + }
>> +
>
> Use rte_eth_dev_is_valid_port() function instead.
>
I missed that.
Thanks.
^ permalink raw reply [flat|nested] 15+ messages in thread
* [dpdk-dev] [PATCH v2 1/5] ethdev: add multicast address filtering
2015-05-28 16:22 ` Stephen Hemminger
2015-05-29 7:52 ` Ivan Boule
@ 2015-05-29 8:56 ` Ivan Boule
2015-05-29 13:12 ` [dpdk-dev] default unicast mac address - was: " Thomas Monjalon
2 siblings, 0 replies; 15+ messages in thread
From: Ivan Boule @ 2015-05-29 8:56 UTC (permalink / raw)
To: dev
With the current PMD API, the receipt of multicast packets on a given
port can only be enabled by invoking the "rte_eth_allmulticast_enable"
function.
This method may not work on Virtual Functions in SR-IOV architectures
when the host PF driver does not allow such operation on VFs.
In such cases, joined multicast addresses must be individually added
in the set of multicast addresses that are filtered by the [VF] port.
For this purpose, a new function "set_mc_addr_list" is introduced
into the set of functions that are exported by a Poll Mode Driver.
Signed-off-by: Ivan Boule <ivan.boule@6wind.com>
---
v2:
Use the dedicated function "rte_eth_dev_is_valid_port" to check
the "port_id" parameter in "rte_eth_dev_set_mc_addr_list".
lib/librte_ether/rte_ethdev.c | 17 +++++++++++++++++
lib/librte_ether/rte_ethdev.h | 26 ++++++++++++++++++++++++++
2 files changed, 43 insertions(+)
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 024fe8b..8001b16 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3628,3 +3628,20 @@ rte_eth_remove_tx_callback(uint8_t port_id, uint16_t queue_id,
/* Callback wasn't found. */
return -EINVAL;
}
+
+int
+rte_eth_dev_set_mc_addr_list(uint8_t port_id,
+ struct ether_addr *mc_addr_set,
+ uint32_t nb_mc_addr)
+{
+ struct rte_eth_dev *dev;
+
+ if (!rte_eth_dev_is_valid_port(port_id)) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return -ENODEV;
+ }
+
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_mc_addr_list, -ENOTSUP);
+ return dev->dev_ops->set_mc_addr_list(dev, mc_addr_set, nb_mc_addr);
+}
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 16dbe00..04c192d 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1228,6 +1228,10 @@ typedef int (*eth_udp_tunnel_del_t)(struct rte_eth_dev *dev,
struct rte_eth_udp_tunnel *tunnel_udp);
/**< @internal Delete tunneling UDP info */
+typedef int (*eth_set_mc_addr_list_t)(struct rte_eth_dev *dev,
+ struct ether_addr *mc_addr_set,
+ uint32_t nb_mc_addr);
+/**< @internal set the list of multicast addresses on an Ethernet device */
#ifdef RTE_NIC_BYPASS
@@ -1386,6 +1390,7 @@ struct eth_dev_ops {
/** Get current RSS hash configuration. */
rss_hash_conf_get_t rss_hash_conf_get;
eth_filter_ctrl_t filter_ctrl; /**< common filter control*/
+ eth_set_mc_addr_list_t set_mc_addr_list; /**< set list of mcast addrs */
};
/**
@@ -3615,4 +3620,25 @@ int rte_eth_remove_tx_callback(uint8_t port_id, uint16_t queue_id,
}
#endif
+/**
+ * Set the list of multicast addresses to filter on an Ethernet device.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param mc_addr_set
+ * The array of multicast addresses to set. Equal to NULL when the function
+ * is invoked to flush the set of filtered addresses.
+ * @param nb_mc_addr
+ * The number of multicast addresses in the *mc_addr_set* array. Equal to 0
+ * when the function is invoked to flush the set of filtered addresses.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-ENOTSUP) if PMD of *port_id* doesn't support multicast filtering.
+ * - (-ENOSPC) if *port_id* has not enough multicast filtering resources.
+ */
+int rte_eth_dev_set_mc_addr_list(uint8_t port_id,
+ struct ether_addr *mc_addr_set,
+ uint32_t nb_mc_addr);
+
#endif /* _RTE_ETHDEV_H_ */
--
1.7.10.4
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [dpdk-dev] default unicast mac address - was: add multicast address filtering
2015-05-28 16:22 ` Stephen Hemminger
2015-05-29 7:52 ` Ivan Boule
2015-05-29 8:56 ` [dpdk-dev] [PATCH v2 " Ivan Boule
@ 2015-05-29 13:12 ` Thomas Monjalon
2015-05-29 15:18 ` Stephen Hemminger
2 siblings, 1 reply; 15+ messages in thread
From: Thomas Monjalon @ 2015-05-29 13:12 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
Hi Stephen,
Looking at mac address management, you and Changchun added an entry in
driver ops to be able to change the default mac address with virtio:
http://dpdk.org/browse/dpdk/commit/?id=5186fb1f37fe986
Other ops functions (mac_addr_add/remove) manage the secondary unicast
mac addresses and have a wrapper function in the API:
http://dpdk.org/doc/api/rte__ethdev_8h.html#aa2b81750086f5f9e55cf65e5cf9f2c58
It seems now that the review of the above patch was too weak and I'd like
these issues to be fixed:
- mac_addr_set must be wrapped by rte_eth_dev_mac_addr_set()
- eth_mac_addr_set_t must be fixed to explicitly state that it
replaces the default address
I'm wondering what was the first intent since virtio_mac_addr_set() is
never called?
^ permalink raw reply [flat|nested] 15+ messages in thread
* [dpdk-dev] [PATCH 2/5] app/testpmd: new command to add/remove multicast MAC addresses
2015-05-28 15:05 [dpdk-dev] [PATCH 0/5] multicast address filtering Ivan Boule
2015-05-28 15:05 ` [dpdk-dev] [PATCH 1/5] ethdev: add " Ivan Boule
@ 2015-05-28 15:05 ` Ivan Boule
2015-05-28 15:05 ` [dpdk-dev] [PATCH 3/5] e1000: add multicast MAC address filtering Ivan Boule
` (4 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Ivan Boule @ 2015-05-28 15:05 UTC (permalink / raw)
To: dev
Add the new interactive command:
mcast_addr add|remove X <mcast_addr>
to add/remove the multicast MAC address <mcast_addr> to/from the set of
multicast addresses filtered by port <X>.
Command used to test the function "rte_eth_dev_set_mc_addr_list"
that has been added to the API of PMDs.
Signed-off-by: Ivan Boule <ivan.boule@6wind.com>
---
app/test-pmd/cmdline.c | 52 ++++++++++++++++++
app/test-pmd/config.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++
app/test-pmd/testpmd.h | 6 ++
3 files changed, 200 insertions(+)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index f01db2a..952a9df 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -8733,6 +8733,57 @@ cmdline_parse_inst_t cmd_set_hash_global_config = {
},
};
+/* *** ADD/REMOVE A MULTICAST MAC ADDRESS TO/FROM A PORT *** */
+struct cmd_mcast_addr_result {
+ cmdline_fixed_string_t mcast_addr_cmd;
+ cmdline_fixed_string_t what;
+ uint8_t port_num;
+ struct ether_addr mc_addr;
+};
+
+static void cmd_mcast_addr_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_mcast_addr_result *res = parsed_result;
+
+ if (!is_multicast_ether_addr(&res->mc_addr)) {
+ printf("Invalid multicast addr %02X:%02X:%02X:%02X:%02X:%02X\n",
+ res->mc_addr.addr_bytes[0], res->mc_addr.addr_bytes[1],
+ res->mc_addr.addr_bytes[2], res->mc_addr.addr_bytes[3],
+ res->mc_addr.addr_bytes[4], res->mc_addr.addr_bytes[5]);
+ return;
+ }
+ if (strcmp(res->what, "add") == 0)
+ mcast_addr_add(res->port_num, &res->mc_addr);
+ else
+ mcast_addr_remove(res->port_num, &res->mc_addr);
+}
+
+cmdline_parse_token_string_t cmd_mcast_addr_cmd =
+ TOKEN_STRING_INITIALIZER(struct cmd_mcast_addr_result,
+ mcast_addr_cmd, "mcast_addr");
+cmdline_parse_token_string_t cmd_mcast_addr_what =
+ TOKEN_STRING_INITIALIZER(struct cmd_mcast_addr_result, what,
+ "add#remove");
+cmdline_parse_token_num_t cmd_mcast_addr_portnum =
+ TOKEN_NUM_INITIALIZER(struct cmd_mcast_addr_result, port_num, UINT8);
+cmdline_parse_token_etheraddr_t cmd_mcast_addr_addr =
+ TOKEN_ETHERADDR_INITIALIZER(struct cmd_mac_addr_result, address);
+
+cmdline_parse_inst_t cmd_mcast_addr = {
+ .f = cmd_mcast_addr_parsed,
+ .data = (void *)0,
+ .help_str = "mcast_addr add|remove X <mcast_addr>: add/remove multicast MAC address on port X",
+ .tokens = {
+ (void *)&cmd_mcast_addr_cmd,
+ (void *)&cmd_mcast_addr_what,
+ (void *)&cmd_mcast_addr_portnum,
+ (void *)&cmd_mcast_addr_addr,
+ NULL,
+ },
+};
+
/* ******************************************************************************** */
/* list of instructions */
@@ -8862,6 +8913,7 @@ cmdline_parse_ctx_t main_ctx[] = {
(cmdline_parse_inst_t *)&cmd_set_sym_hash_ena_per_port,
(cmdline_parse_inst_t *)&cmd_get_hash_global_config,
(cmdline_parse_inst_t *)&cmd_set_hash_global_config,
+ (cmdline_parse_inst_t *)&cmd_mcast_addr,
NULL,
};
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index f788ed5..52917c7 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -2130,3 +2130,145 @@ set_vf_rate_limit(portid_t port_id, uint16_t vf, uint16_t rate, uint64_t q_msk)
port_id, diag);
return diag;
}
+
+/*
+ * Functions to manage the set of filtered Multicast MAC addresses.
+ *
+ * A pool of filtered multicast MAC addresses is associated with each port.
+ * The pool is allocated in chunks of MCAST_POOL_INC multicast addresses.
+ * The address of the pool and the number of valid multicast MAC addresses
+ * recorded in the pool are stored in the fields "mc_addr_pool" and
+ * "mc_addr_nb" of the "rte_port" data structure.
+ *
+ * The function "rte_eth_dev_set_mc_addr_list" of the PMDs API imposes
+ * to be supplied a contiguous array of multicast MAC addresses.
+ * To comply with this constraint, the set of multicast addresses recorded
+ * into the pool are systematically compacted at the beginning of the pool.
+ * Hence, when a multicast address is removed from the pool, all following
+ * addresses, if any, are copied back to keep the set contiguous.
+ */
+#define MCAST_POOL_INC 32
+
+static int
+mcast_addr_pool_extend(struct rte_port *port)
+{
+ struct ether_addr *mc_pool;
+ size_t mc_pool_size;
+
+ /*
+ * If a free entry is available at the end of the pool, just
+ * increment the number of recorded multicast addresses.
+ */
+ if ((port->mc_addr_nb % MCAST_POOL_INC) != 0) {
+ port->mc_addr_nb++;
+ return 0;
+ }
+
+ /*
+ * [re]allocate a pool with MCAST_POOL_INC more entries.
+ * The previous test guarantees that port->mc_addr_nb is a multiple
+ * of MCAST_POOL_INC.
+ */
+ mc_pool_size = sizeof(struct ether_addr) * (port->mc_addr_nb +
+ MCAST_POOL_INC);
+ mc_pool = (struct ether_addr *) realloc(port->mc_addr_pool,
+ mc_pool_size);
+ if (mc_pool == NULL) {
+ printf("allocation of pool of %u multicast addresses failed\n",
+ port->mc_addr_nb + MCAST_POOL_INC);
+ return -ENOMEM;
+ }
+
+ port->mc_addr_pool = mc_pool;
+ port->mc_addr_nb++;
+ return 0;
+
+}
+
+static void
+mcast_addr_pool_remove(struct rte_port *port, uint32_t addr_idx)
+{
+ port->mc_addr_nb--;
+ if (addr_idx == port->mc_addr_nb) {
+ /* No need to recompact the set of multicast addressses. */
+ if (port->mc_addr_nb == 0) {
+ /* free the pool of multicast addresses. */
+ free(port->mc_addr_pool);
+ port->mc_addr_pool = NULL;
+ }
+ return;
+ }
+ memmove(&port->mc_addr_pool[addr_idx],
+ &port->mc_addr_pool[addr_idx + 1],
+ sizeof(struct ether_addr) * (port->mc_addr_nb - addr_idx));
+}
+
+static void
+eth_port_multicast_addr_list_set(uint8_t port_id)
+{
+ struct rte_port *port;
+ int diag;
+
+ port = &ports[port_id];
+ diag = rte_eth_dev_set_mc_addr_list(port_id, port->mc_addr_pool,
+ port->mc_addr_nb);
+ if (diag == 0)
+ return;
+ printf("rte_eth_dev_set_mc_addr_list(port=%d, nb=%u) failed. diag=%d\n",
+ port->mc_addr_nb, port_id, -diag);
+}
+
+void
+mcast_addr_add(uint8_t port_id, struct ether_addr *mc_addr)
+{
+ struct rte_port *port;
+ uint32_t i;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN))
+ return;
+
+ port = &ports[port_id];
+
+ /*
+ * Check that the added multicast MAC address is not already recorded
+ * in the pool of multicast addresses.
+ */
+ for (i = 0; i < port->mc_addr_nb; i++) {
+ if (is_same_ether_addr(mc_addr, &port->mc_addr_pool[i])) {
+ printf("multicast address already filtered by port\n");
+ return;
+ }
+ }
+
+ if (mcast_addr_pool_extend(port) != 0)
+ return;
+ ether_addr_copy(mc_addr, &port->mc_addr_pool[i]);
+ eth_port_multicast_addr_list_set(port_id);
+}
+
+void
+mcast_addr_remove(uint8_t port_id, struct ether_addr *mc_addr)
+{
+ struct rte_port *port;
+ uint32_t i;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN))
+ return;
+
+ port = &ports[port_id];
+
+ /*
+ * Search the pool of multicast MAC addresses for the removed address.
+ */
+ for (i = 0; i < port->mc_addr_nb; i++) {
+ if (is_same_ether_addr(mc_addr, &port->mc_addr_pool[i]))
+ break;
+ }
+ if (i == port->mc_addr_nb) {
+ printf("multicast address not filtered by port %d\n", port_id);
+ return;
+ }
+
+ mcast_addr_pool_remove(port, i);
+ eth_port_multicast_addr_list_set(port_id);
+}
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index c3b6700..f2c84d9 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -162,6 +162,8 @@ struct rte_port {
uint8_t dcb_flag; /**< enable dcb */
struct rte_eth_rxconf rx_conf; /**< rx configuration */
struct rte_eth_txconf tx_conf; /**< tx configuration */
+ struct ether_addr *mc_addr_pool; /**< pool of multicast addrs */
+ uint32_t mc_addr_nb; /**< nb. of addr. in mc_addr_pool */
};
extern portid_t __rte_unused
@@ -563,6 +565,10 @@ void get_5tuple_filter(uint8_t port_id, uint16_t index);
int rx_queue_id_is_invalid(queueid_t rxq_id);
int tx_queue_id_is_invalid(queueid_t txq_id);
+/* Functions to manage the set of filtered Multicast MAC addresses */
+void mcast_addr_add(uint8_t port_id, struct ether_addr *mc_addr);
+void mcast_addr_remove(uint8_t port_id, struct ether_addr *mc_addr);
+
enum print_warning {
ENABLED_WARN = 0,
DISABLED_WARN
--
1.7.10.4
^ permalink raw reply [flat|nested] 15+ messages in thread
* [dpdk-dev] [PATCH 3/5] e1000: add multicast MAC address filtering
2015-05-28 15:05 [dpdk-dev] [PATCH 0/5] multicast address filtering Ivan Boule
2015-05-28 15:05 ` [dpdk-dev] [PATCH 1/5] ethdev: add " Ivan Boule
2015-05-28 15:05 ` [dpdk-dev] [PATCH 2/5] app/testpmd: new command to add/remove multicast MAC addresses Ivan Boule
@ 2015-05-28 15:05 ` Ivan Boule
2015-05-28 15:05 ` [dpdk-dev] [PATCH 4/5] ixgbe: " Ivan Boule
` (3 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Ivan Boule @ 2015-05-28 15:05 UTC (permalink / raw)
To: dev
Support the PMD function "set_mc_addr_list" in the "igb", "igb-vf",
and "em" Poll Mode Drivers.
Signed-off-by: Ivan Boule <ivan.boule@6wind.com>
---
drivers/net/e1000/em_ethdev.c | 17 +++++++++++++++++
drivers/net/e1000/igb_ethdev.c | 18 ++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index d28030e..2392942 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -116,6 +116,10 @@ static void eth_em_rar_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
uint32_t index, uint32_t pool);
static void eth_em_rar_clear(struct rte_eth_dev *dev, uint32_t index);
+static int eth_em_set_mc_addr_list(struct rte_eth_dev *dev,
+ struct ether_addr *mc_addr_set,
+ uint32_t nb_mc_addr);
+
#define EM_FC_PAUSE_TIME 0x0680
#define EM_LINK_UPDATE_CHECK_TIMEOUT 90 /* 9s */
#define EM_LINK_UPDATE_CHECK_INTERVAL 100 /* ms */
@@ -161,6 +165,7 @@ static const struct eth_dev_ops eth_em_ops = {
.flow_ctrl_set = eth_em_flow_ctrl_set,
.mac_addr_add = eth_em_rar_set,
.mac_addr_remove = eth_em_rar_clear,
+ .set_mc_addr_list = eth_em_set_mc_addr_list,
};
/**
@@ -1522,6 +1527,18 @@ eth_em_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
return 0;
}
+static int
+eth_em_set_mc_addr_list(struct rte_eth_dev *dev,
+ struct ether_addr *mc_addr_set,
+ uint32_t nb_mc_addr)
+{
+ struct e1000_hw *hw;
+
+ hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ e1000_update_mc_addr_list(hw, (u8 *)mc_addr_set, nb_mc_addr);
+ return 0;
+}
+
struct rte_driver em_pmd_drv = {
.type = PMD_PDEV,
.init = rte_em_pmd_init,
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index e4b370d..1c24edc 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -194,6 +194,10 @@ static int eth_igb_filter_ctrl(struct rte_eth_dev *dev,
enum rte_filter_op filter_op,
void *arg);
+static int eth_igb_set_mc_addr_list(struct rte_eth_dev *dev,
+ struct ether_addr *mc_addr_set,
+ uint32_t nb_mc_addr);
+
/*
* Define VF Stats MACRO for Non "cleared on read" register
*/
@@ -269,6 +273,7 @@ static const struct eth_dev_ops eth_igb_ops = {
.rss_hash_update = eth_igb_rss_hash_update,
.rss_hash_conf_get = eth_igb_rss_hash_conf_get,
.filter_ctrl = eth_igb_filter_ctrl,
+ .set_mc_addr_list = eth_igb_set_mc_addr_list,
};
/*
@@ -289,6 +294,7 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = {
.rx_queue_release = eth_igb_rx_queue_release,
.tx_queue_setup = eth_igb_tx_queue_setup,
.tx_queue_release = eth_igb_tx_queue_release,
+ .set_mc_addr_list = eth_igb_set_mc_addr_list,
};
/**
@@ -3642,6 +3648,18 @@ eth_igb_filter_ctrl(struct rte_eth_dev *dev,
return ret;
}
+static int
+eth_igb_set_mc_addr_list(struct rte_eth_dev *dev,
+ struct ether_addr *mc_addr_set,
+ uint32_t nb_mc_addr)
+{
+ struct e1000_hw *hw;
+
+ hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ e1000_update_mc_addr_list(hw, (u8 *)mc_addr_set, nb_mc_addr);
+ return 0;
+}
+
static struct rte_driver pmd_igb_drv = {
.type = PMD_PDEV,
.init = rte_igb_pmd_init,
--
1.7.10.4
^ permalink raw reply [flat|nested] 15+ messages in thread
* [dpdk-dev] [PATCH 4/5] ixgbe: add multicast MAC address filtering
2015-05-28 15:05 [dpdk-dev] [PATCH 0/5] multicast address filtering Ivan Boule
` (2 preceding siblings ...)
2015-05-28 15:05 ` [dpdk-dev] [PATCH 3/5] e1000: add multicast MAC address filtering Ivan Boule
@ 2015-05-28 15:05 ` Ivan Boule
2015-05-28 15:05 ` [dpdk-dev] [PATCH 5/5] app/testpmd: fix reply to a multicast ICMP request Ivan Boule
` (2 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Ivan Boule @ 2015-05-28 15:05 UTC (permalink / raw)
To: dev
Support the function "set_mc_addr_list" in the "ixgbe" and in the
"ixgbe-vf" Poll Mode Drivers.
Signed-off-by: Ivan Boule <ivan.boule@6wind.com>
---
drivers/net/ixgbe/ixgbe_ethdev.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 0d9f9b2..885ed8f 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -257,6 +257,10 @@ static int ixgbe_dev_filter_ctrl(struct rte_eth_dev *dev,
void *arg);
static int ixgbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu);
+static int ixgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev,
+ struct ether_addr *mc_addr_set,
+ uint32_t nb_mc_addr);
+
/*
* Define VF Stats MACRO for Non "cleared on read" register
*/
@@ -381,6 +385,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
.rss_hash_update = ixgbe_dev_rss_hash_update,
.rss_hash_conf_get = ixgbe_dev_rss_hash_conf_get,
.filter_ctrl = ixgbe_dev_filter_ctrl,
+ .set_mc_addr_list = ixgbe_dev_set_mc_addr_list,
};
/*
@@ -406,6 +411,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
.tx_queue_release = ixgbe_dev_tx_queue_release,
.mac_addr_add = ixgbevf_add_mac_addr,
.mac_addr_remove = ixgbevf_remove_mac_addr,
+ .set_mc_addr_list = ixgbe_dev_set_mc_addr_list,
};
/**
@@ -4439,6 +4445,32 @@ ixgbe_dev_filter_ctrl(struct rte_eth_dev *dev,
return ret;
}
+static u8 *
+ixgbe_dev_addr_list_itr(__attribute__((unused)) struct ixgbe_hw *hw,
+ u8 **mc_addr_ptr, u32 *vmdq)
+{
+ u8 *mc_addr;
+
+ *vmdq = 0;
+ mc_addr = *mc_addr_ptr;
+ *mc_addr_ptr = (mc_addr + sizeof(struct ether_addr));
+ return mc_addr;
+}
+
+static int
+ixgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev,
+ struct ether_addr *mc_addr_set,
+ uint32_t nb_mc_addr)
+{
+ struct ixgbe_hw *hw;
+ u8 *mc_addr_list;
+
+ hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ mc_addr_list = (u8 *)mc_addr_set;
+ return ixgbe_update_mc_addr_list(hw, mc_addr_list, nb_mc_addr,
+ ixgbe_dev_addr_list_itr, TRUE);
+}
+
static struct rte_driver rte_ixgbe_driver = {
.type = PMD_PDEV,
.init = rte_ixgbe_pmd_init,
--
1.7.10.4
^ permalink raw reply [flat|nested] 15+ messages in thread
* [dpdk-dev] [PATCH 5/5] app/testpmd: fix reply to a multicast ICMP request
2015-05-28 15:05 [dpdk-dev] [PATCH 0/5] multicast address filtering Ivan Boule
` (3 preceding siblings ...)
2015-05-28 15:05 ` [dpdk-dev] [PATCH 4/5] ixgbe: " Ivan Boule
@ 2015-05-28 15:05 ` Ivan Boule
2015-05-28 16:21 ` [dpdk-dev] [PATCH 0/5] multicast address filtering Stephen Hemminger
2015-06-12 13:58 ` Thomas Monjalon
6 siblings, 0 replies; 15+ messages in thread
From: Ivan Boule @ 2015-05-28 15:05 UTC (permalink / raw)
To: dev
Set the IP source and destination addresses in the IP header of the
ICMP reply as follows:
- Use the request IP source address as the reply IP destination address
- If the request IP destination address is a multicast IP address
- choose a reply IP source address different from the request IP
source address,
- re-compute the IP header checksum.
Otherwise
- switch the request IP source and destination addresses in the
reply,
- keep the IP header checksum unchanged.
Signed-off-by: Ivan Boule <ivan.boule@6wind.com>
---
app/test-pmd/icmpecho.c | 65 ++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 59 insertions(+), 6 deletions(-)
diff --git a/app/test-pmd/icmpecho.c b/app/test-pmd/icmpecho.c
index 010c5a9..9e6f5e9 100644
--- a/app/test-pmd/icmpecho.c
+++ b/app/test-pmd/icmpecho.c
@@ -272,6 +272,30 @@ ipv4_addr_dump(const char *what, uint32_t be_ipv4_addr)
printf("%s", buf);
}
+static uint16_t
+ipv4_hdr_cksum(struct ipv4_hdr *ip_h)
+{
+ uint16_t *v16_h;
+ uint32_t ip_cksum;
+
+ /*
+ * Compute the sum of successive 16-bit words of the IPv4 header,
+ * skipping the checksum field of the header.
+ */
+ v16_h = (uint16_t *) ip_h;
+ ip_cksum = v16_h[0] + v16_h[1] + v16_h[2] + v16_h[3] +
+ v16_h[4] + v16_h[6] + v16_h[7] + v16_h[8] + v16_h[9];
+
+ /* reduce 32 bit checksum to 16 bits and complement it */
+ ip_cksum = (ip_cksum & 0xffff) + (ip_cksum >> 16);
+ ip_cksum = (ip_cksum & 0xffff) + (ip_cksum >> 16);
+ ip_cksum = (~ip_cksum) & 0x0000FFFF;
+ return (ip_cksum == 0) ? 0xFFFF : (uint16_t) ip_cksum;
+}
+
+#define is_multicast_ipv4_addr(ipv4_addr) \
+ (((rte_be_to_cpu_32((ipv4_addr)) >> 24) & 0x000000FF) == 0xE0)
+
/*
* Receive a burst of packets, lookup for ICMP echo requets, and, if any,
* send back ICMP echo replies.
@@ -295,6 +319,7 @@ reply_to_icmp_echo_rqsts(struct fwd_stream *fs)
uint16_t vlan_id;
uint16_t arp_op;
uint16_t arp_pro;
+ uint32_t cksum;
uint8_t i;
int l2_len;
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
@@ -442,19 +467,47 @@ reply_to_icmp_echo_rqsts(struct fwd_stream *fs)
/*
* Prepare ICMP echo reply to be sent back.
* - switch ethernet source and destinations addresses,
- * - switch IPv4 source and destinations addresses,
+ * - use the request IP source address as the reply IP
+ * destination address,
+ * - if the request IP destination address is a multicast
+ * address:
+ * - choose a reply IP source address different from the
+ * request IP source address,
+ * - re-compute the IP header checksum.
+ * Otherwise:
+ * - switch the request IP source and destination
+ * addresses in the reply IP header,
+ * - keep the IP header checksum unchanged.
* - set IP_ICMP_ECHO_REPLY in ICMP header.
- * No need to re-compute the IP header checksum.
- * Reset ICMP checksum.
+ * ICMP checksum is computed by assuming it is valid in the
+ * echo request and not verified.
*/
ether_addr_copy(ð_h->s_addr, ð_addr);
ether_addr_copy(ð_h->d_addr, ð_h->s_addr);
ether_addr_copy(ð_addr, ð_h->d_addr);
ip_addr = ip_h->src_addr;
- ip_h->src_addr = ip_h->dst_addr;
- ip_h->dst_addr = ip_addr;
+ if (is_multicast_ipv4_addr(ip_h->dst_addr)) {
+ uint32_t ip_src;
+
+ ip_src = rte_be_to_cpu_32(ip_addr);
+ if ((ip_src & 0x00000003) == 1)
+ ip_src = (ip_src & 0xFFFFFFFC) | 0x00000002;
+ else
+ ip_src = (ip_src & 0xFFFFFFFC) | 0x00000001;
+ ip_h->src_addr = rte_cpu_to_be_32(ip_src);
+ ip_h->dst_addr = ip_addr;
+ ip_h->hdr_checksum = ipv4_hdr_cksum(ip_h);
+ } else {
+ ip_h->src_addr = ip_h->dst_addr;
+ ip_h->dst_addr = ip_addr;
+ }
icmp_h->icmp_type = IP_ICMP_ECHO_REPLY;
- icmp_h->icmp_cksum = 0;
+ cksum = ~icmp_h->icmp_cksum & 0xffff;
+ cksum += ~htons(IP_ICMP_ECHO_REQUEST << 8) & 0xffff;
+ cksum += htons(IP_ICMP_ECHO_REPLY << 8);
+ cksum = (cksum & 0xffff) + (cksum >> 16);
+ cksum = (cksum & 0xffff) + (cksum >> 16);
+ icmp_h->icmp_cksum = ~cksum;
pkts_burst[nb_replies++] = pkt;
}
--
1.7.10.4
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [dpdk-dev] [PATCH 0/5] multicast address filtering
2015-05-28 15:05 [dpdk-dev] [PATCH 0/5] multicast address filtering Ivan Boule
` (4 preceding siblings ...)
2015-05-28 15:05 ` [dpdk-dev] [PATCH 5/5] app/testpmd: fix reply to a multicast ICMP request Ivan Boule
@ 2015-05-28 16:21 ` Stephen Hemminger
2015-05-29 9:33 ` Ivan Boule
2015-06-12 13:58 ` Thomas Monjalon
6 siblings, 1 reply; 15+ messages in thread
From: Stephen Hemminger @ 2015-05-28 16:21 UTC (permalink / raw)
To: Ivan Boule; +Cc: dev
On Thu, 28 May 2015 17:05:18 +0200
Ivan Boule <ivan.boule@6wind.com> wrote:
> Introduce PMD API to set the list of multicast MAC addresses filtered
> by a port.
> Implemented in the following PMDs: igb, igbvf, em, ixgbe, and ixgbevf.
> Implementation for physical PMDs i40e, i40evf, enic, and fm10k left
> to their respective maintainers.
>
> Ivan Boule (5):
> ethdev: add multicast address filtering
> app/testpmd: new command to add/remove multicast MAC addresses
> e1000: add multicast MAC address filtering
> ixgbe: add multicast MAC address filtering
> app/testpmd: fix reply to a multicast ICMP request
>
> app/test-pmd/cmdline.c | 52 ++++++++++++++
> app/test-pmd/config.c | 142 ++++++++++++++++++++++++++++++++++++++
> app/test-pmd/icmpecho.c | 65 +++++++++++++++--
> app/test-pmd/testpmd.h | 6 ++
> drivers/net/e1000/em_ethdev.c | 17 +++++
> drivers/net/e1000/igb_ethdev.c | 18 +++++
> drivers/net/ixgbe/ixgbe_ethdev.c | 32 +++++++++
> lib/librte_ether/rte_ethdev.c | 17 +++++
> lib/librte_ether/rte_ethdev.h | 26 +++++++
> 9 files changed, 369 insertions(+), 6 deletions(-)
>
Looks good, could you also add support for virtio and vmxnet3?
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [dpdk-dev] [PATCH 0/5] multicast address filtering
2015-05-28 16:21 ` [dpdk-dev] [PATCH 0/5] multicast address filtering Stephen Hemminger
@ 2015-05-29 9:33 ` Ivan Boule
2015-05-29 15:17 ` Stephen Hemminger
0 siblings, 1 reply; 15+ messages in thread
From: Ivan Boule @ 2015-05-29 9:33 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
On 05/28/2015 06:21 PM, Stephen Hemminger wrote:
> On Thu, 28 May 2015 17:05:18 +0200
> Ivan Boule <ivan.boule@6wind.com> wrote:
>
>> Introduce PMD API to set the list of multicast MAC addresses filtered
>> by a port.
>> Implemented in the following PMDs: igb, igbvf, em, ixgbe, and ixgbevf.
>> Implementation for physical PMDs i40e, i40evf, enic, and fm10k left
>> to their respective maintainers.
>>
>> Ivan Boule (5):
>> ethdev: add multicast address filtering
>> app/testpmd: new command to add/remove multicast MAC addresses
>> e1000: add multicast MAC address filtering
>> ixgbe: add multicast MAC address filtering
>> app/testpmd: fix reply to a multicast ICMP request
>>
>> app/test-pmd/cmdline.c | 52 ++++++++++++++
>> app/test-pmd/config.c | 142 ++++++++++++++++++++++++++++++++++++++
>> app/test-pmd/icmpecho.c | 65 +++++++++++++++--
>> app/test-pmd/testpmd.h | 6 ++
>> drivers/net/e1000/em_ethdev.c | 17 +++++
>> drivers/net/e1000/igb_ethdev.c | 18 +++++
>> drivers/net/ixgbe/ixgbe_ethdev.c | 32 +++++++++
>> lib/librte_ether/rte_ethdev.c | 17 +++++
>> lib/librte_ether/rte_ethdev.h | 26 +++++++
>> 9 files changed, 369 insertions(+), 6 deletions(-)
>>
>
> Looks good, could you also add support for virtio and vmxnet3?
>
As for physical NICs (i40e, etc.) listed above, I let the maintainers of
the remaining NICs where this function is relevant to implement and to
test it.
By the way, I supposed that Guest front-end vNICs were always in
promiscuous mode by construction.
Said differently: that all packets supplied "from the outside" to the
Host vNIC back-end driver were systematically delivered to the Guest
vNIC front-end, whatever their destination MAC address, VLAN id., etc.
Did I missed something ?
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [dpdk-dev] [PATCH 0/5] multicast address filtering
2015-05-29 9:33 ` Ivan Boule
@ 2015-05-29 15:17 ` Stephen Hemminger
0 siblings, 0 replies; 15+ messages in thread
From: Stephen Hemminger @ 2015-05-29 15:17 UTC (permalink / raw)
To: Ivan Boule; +Cc: dev
On Fri, 29 May 2015 11:33:54 +0200
Ivan Boule <ivan.boule@6wind.com> wrote:
> On 05/28/2015 06:21 PM, Stephen Hemminger wrote:
> > On Thu, 28 May 2015 17:05:18 +0200
> > Ivan Boule <ivan.boule@6wind.com> wrote:
> >
> >> Introduce PMD API to set the list of multicast MAC addresses filtered
> >> by a port.
> >> Implemented in the following PMDs: igb, igbvf, em, ixgbe, and ixgbevf.
> >> Implementation for physical PMDs i40e, i40evf, enic, and fm10k left
> >> to their respective maintainers.
> >>
> >> Ivan Boule (5):
> >> ethdev: add multicast address filtering
> >> app/testpmd: new command to add/remove multicast MAC addresses
> >> e1000: add multicast MAC address filtering
> >> ixgbe: add multicast MAC address filtering
> >> app/testpmd: fix reply to a multicast ICMP request
> >>
> >> app/test-pmd/cmdline.c | 52 ++++++++++++++
> >> app/test-pmd/config.c | 142 ++++++++++++++++++++++++++++++++++++++
> >> app/test-pmd/icmpecho.c | 65 +++++++++++++++--
> >> app/test-pmd/testpmd.h | 6 ++
> >> drivers/net/e1000/em_ethdev.c | 17 +++++
> >> drivers/net/e1000/igb_ethdev.c | 18 +++++
> >> drivers/net/ixgbe/ixgbe_ethdev.c | 32 +++++++++
> >> lib/librte_ether/rte_ethdev.c | 17 +++++
> >> lib/librte_ether/rte_ethdev.h | 26 +++++++
> >> 9 files changed, 369 insertions(+), 6 deletions(-)
> >>
> >
> > Looks good, could you also add support for virtio and vmxnet3?
> >
> As for physical NICs (i40e, etc.) listed above, I let the maintainers of
> the remaining NICs where this function is relevant to implement and to
> test it.
> By the way, I supposed that Guest front-end vNICs were always in
> promiscuous mode by construction.
> Said differently: that all packets supplied "from the outside" to the
> Host vNIC back-end driver were systematically delivered to the Guest
> vNIC front-end, whatever their destination MAC address, VLAN id., etc.
> Did I missed something ?
>
For virtio, there is a mac address table, and Multicast filtering is done
by adding the multicast address to the macs table.
For vmxnet3, ther is multicast address table (shared with host) so that
multicast filtering can be done hypervisor.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [dpdk-dev] [PATCH 0/5] multicast address filtering
2015-05-28 15:05 [dpdk-dev] [PATCH 0/5] multicast address filtering Ivan Boule
` (5 preceding siblings ...)
2015-05-28 16:21 ` [dpdk-dev] [PATCH 0/5] multicast address filtering Stephen Hemminger
@ 2015-06-12 13:58 ` Thomas Monjalon
6 siblings, 0 replies; 15+ messages in thread
From: Thomas Monjalon @ 2015-06-12 13:58 UTC (permalink / raw)
To: Ivan Boule; +Cc: dev
2015-05-28 17:05, Ivan Boule:
> Introduce PMD API to set the list of multicast MAC addresses filtered
> by a port.
> Implemented in the following PMDs: igb, igbvf, em, ixgbe, and ixgbevf.
> Implementation for physical PMDs i40e, i40evf, enic, and fm10k left
> to their respective maintainers.
>
> Ivan Boule (5):
> ethdev: add multicast address filtering
> app/testpmd: new command to add/remove multicast MAC addresses
> e1000: add multicast MAC address filtering
> ixgbe: add multicast MAC address filtering
> app/testpmd: fix reply to a multicast ICMP request
The new symbol was not exported in the .map file (fixed before push).
Applied, thanks
^ permalink raw reply [flat|nested] 15+ messages in thread