5.3. spp_mirror¶
This section describes implementation of spp_mirror
.
It consists of master thread and several worker threads for duplicating
packets.
5.3.1. Slave Main¶
Main function of worker thread is defined as slave_main()
in which
for duplicating packets is mirror_proc()
on each of lcores.
for (cnt = 0; cnt < core->num; cnt++) {
ret = mirror_proc(core->id[cnt]);
if (unlikely(ret != 0))
break;
}
5.3.2. Mirroring Packets¶
Worker thread receives and duplicate packets. There are two modes of copying
packets, shallowcopy
and deepcopy
.
Deep copy is for duplicating whole of packet data, but less performance than
shallow copy. Shallow copy duplicates only packet header and body is not shared
among original packet and duplicated packet. So, changing packet data affects
both of original and copied packet.
You can configure using which of modes in Makefile. Default mode is
shallowcopy
. If you change the mode to deepcopy
, comment out this
line of CFLAGS.
# Default mode is shallow copy.
CFLAGS += -DSPP_MIRROR_SHALLOWCOPY
This code is a part of mirror_proc()
. In this function,
rte_pktmbuf_clone()
is just called if in shallow copy
mode, or create a new packet with rte_pktmbuf_alloc()
for duplicated
packet if in deep copy mode.
for (cnt = 0; cnt < nb_rx; cnt++) {
org_mbuf = bufs[cnt];
rte_prefetch0(rte_pktmbuf_mtod(org_mbuf, void *));
#ifdef SPP_MIRROR_SHALLOWCOPY
/* Shallow Copy */
copybufs[cnt] = rte_pktmbuf_clone(org_mbuf,
g_mirror_pool);
#else
struct rte_mbuf *mirror_mbuf = NULL;
struct rte_mbuf **mirror_mbufs = &mirror_mbuf;
struct rte_mbuf *copy_mbuf = NULL;
/* Deep Copy */
do {
copy_mbuf = rte_pktmbuf_alloc(g_mirror_pool);
if (unlikely(copy_mbuf == NULL)) {
rte_pktmbuf_free(mirror_mbuf);
mirror_mbuf = NULL;
RTE_LOG(INFO, MIRROR,
"copy mbuf alloc NG!\n");
break;
}
copy_mbuf->data_off = org_mbuf->data_off;
...
copy_mbuf->packet_type = org_mbuf->packet_type;
rte_memcpy(rte_pktmbuf_mtod(copy_mbuf, char *),
rte_pktmbuf_mtod(org_mbuf, char *),
org_mbuf->data_len);
*mirror_mbufs = copy_mbuf;
mirror_mbufs = ©_mbuf->next;
} while ((org_mbuf = org_mbuf->next) != NULL);
copybufs[cnt] = mirror_mbuf;
#endif /* SPP_MIRROR_SHALLOWCOPY */
}
if (cnt != 0)
nb_tx2 = spp_eth_tx_burst(tx->dpdk_port, 0,
copybufs, cnt);