This patch add port based mirroring support for the mirror lib. The port based mirroring is unconditional traffic mirroring between 2 ethdev ports.
Signed-off-by: Liang-min Wang <liang-min.w...@intel.com> Signed-off-by: Patrick Fu <patrick...@intel.com> Signed-off-by: Timothy Miskell <timothy.misk...@intel.com> --- lib/librte_mirror/rte_mirror.c | 57 ++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/lib/librte_mirror/rte_mirror.c b/lib/librte_mirror/rte_mirror.c index f2a85976a..d2c0d8eab 100644 --- a/lib/librte_mirror/rte_mirror.c +++ b/lib/librte_mirror/rte_mirror.c @@ -196,6 +196,57 @@ mirror_pkt_update(struct rte_mbuf *pkt, uint16_t dst_vlan_id) rte_mbuf_refcnt_update(pkt, 1); } +static inline uint16_t +mirror_port_cb(uint16_t qidx, struct rte_mbuf **pkts, + uint16_t nb_pkts, void *user_params) +{ + struct rte_mirror_param *data = user_params; + uint16_t i, dst_qidx; + uint16_t pkt_trans; + uint16_t dst_port_id = data->dst_port_id; + uint16_t dst_vlan_id = data->dst_vlan_id; + + if (nb_pkts == 0) + return 0; + + for (i = 0; i < nb_pkts; i++) + mirror_pkt_update(pkts[i], dst_vlan_id); + + dst_qidx = data->n_dst_queue > qidx ? qidx : data->n_dst_queue - 1; + + rte_spinlock_lock(&data->locks[dst_qidx]); + pkt_trans = rte_eth_tx_burst(dst_port_id, dst_qidx, pkts, nb_pkts); + rte_spinlock_unlock(&data->locks[dst_qidx]); + if (pkt_trans != nb_pkts) + RTE_ETHDEV_LOG(ERR, "%d packets for tapping but " + "only %d packet get through\n", nb_pkts, pkt_trans); + + for (i = 0; i < nb_pkts; i++) + pkts[i]->ol_flags &= ~VLAN_INSERT_FLAG; + + while (unlikely(pkt_trans < nb_pkts)) { + rte_pktmbuf_free(pkts[pkt_trans]); + pkt_trans++; + } + + return nb_pkts; +} + +static uint16_t +mirror_rx_port_cb(uint16_t port_id __rte_unused, uint16_t qidx, + struct rte_mbuf **pkts, uint16_t nb_pkts, + uint16_t max_pkts __rte_unused, void *user_params) +{ + return mirror_port_cb(qidx, pkts, nb_pkts, user_params); +} + +static uint16_t +mirror_tx_port_cb(uint16_t port_id __rte_unused, uint16_t qidx, + struct rte_mbuf **pkts, uint16_t nb_pkts, void *user_params) +{ + return mirror_port_cb(qidx, pkts, nb_pkts, user_params); +} + int rte_mirror_offload_register(uint16_t src_port, struct rte_mirror_param *param, int tx_cb) @@ -221,6 +272,12 @@ rte_mirror_offload_register(uint16_t src_port, } switch (data->mirror_type) { + case rte_mirror_type_port: + if (tx_cb) + tx_fn = mirror_tx_port_cb; + else + rx_fn = mirror_rx_port_cb; + break; default: MIRROR_LOG(ERR, "Un-supported mirror offloading type!!!\n"); return -ENOTSUP; -- 2.18.4