Fix bug: incorrect usage of `rte_pktmbuf_clone` when dispatching arp packets.

Since f-stack uses `rte_pktmbuf_clone` to copy mbuf to other lcores when dispatching arp packets, but it doesn't real copy the packet data. The buf_addr of pktmbuf is pointed to the same address.

The arp response packet is generated with the same mbuf from the request
packet, it just swaps the src and dst address, so the copied mbufs will also be changed.

What we need is a deep copy function, and the arp packets are really small, so deep copy will not harm performance too much.

Fix #53 #111 #112.
This commit is contained in:
logwang 2017-12-01 16:55:31 +08:00
parent aa3f528959
commit 48b700b73c
1 changed files with 66 additions and 4 deletions

View File

@ -898,6 +898,66 @@ protocol_filter(const void *data, uint16_t len)
len - ETHER_HDR_LEN);
}
static inline void
pktmbuf_deep_attach(struct rte_mbuf *mi, const struct rte_mbuf *m)
{
struct rte_mbuf *md;
void *src, *dst;
dst = rte_pktmbuf_mtod(mi, void *);
src = rte_pktmbuf_mtod(m, void *);
mi->data_len = m->data_len;
rte_memcpy(dst, src, m->data_len);
mi->port = m->port;
mi->vlan_tci = m->vlan_tci;
mi->vlan_tci_outer = m->vlan_tci_outer;
mi->tx_offload = m->tx_offload;
mi->hash = m->hash;
mi->ol_flags = m->ol_flags;
mi->packet_type = m->packet_type;
}
/* copied from rte_pktmbuf_clone */
static inline struct rte_mbuf *
pktmbuf_deep_clone(const struct rte_mbuf *md,
struct rte_mempool *mp)
{
struct rte_mbuf *mc, *mi, **prev;
uint32_t pktlen;
uint8_t nseg;
if (unlikely ((mc = rte_pktmbuf_alloc(mp)) == NULL))
return NULL;
mi = mc;
prev = &mi->next;
pktlen = md->pkt_len;
nseg = 0;
do {
nseg++;
pktmbuf_deep_attach(mi, md);
*prev = mi;
prev = &mi->next;
} while ((md = md->next) != NULL &&
(mi = rte_pktmbuf_alloc(mp)) != NULL);
*prev = NULL;
mc->nb_segs = nseg;
mc->pkt_len = pktlen;
/* Allocation of new indirect segment failed */
if (unlikely (mi == NULL)) {
rte_pktmbuf_free(mc);
return NULL;
}
__rte_mbuf_sanity_check(mc, 1);
return mc;
}
static inline void
process_packets(uint8_t port_id, uint16_t queue_id, struct rte_mbuf **bufs,
uint16_t count, const struct ff_dpdk_if_context *ctx, int pkts_from_ring)
@ -950,9 +1010,10 @@ process_packets(uint8_t port_id, uint16_t queue_id, struct rte_mbuf **bufs,
socket_id = rte_lcore_to_socket_id(lcore_id);
}
mbuf_pool = pktmbuf_pool[socket_id];
mbuf_clone = rte_pktmbuf_clone(rtem, mbuf_pool);
mbuf_clone = pktmbuf_deep_clone(rtem, mbuf_pool);
if(mbuf_clone) {
int ret = rte_ring_enqueue(dispatch_ring[port_id][j], mbuf_clone);
int ret = rte_ring_enqueue(dispatch_ring[port_id][j],
mbuf_clone);
if (ret < 0)
rte_pktmbuf_free(mbuf_clone);
}
@ -961,14 +1022,15 @@ process_packets(uint8_t port_id, uint16_t queue_id, struct rte_mbuf **bufs,
if (enable_kni && rte_eal_process_type() == RTE_PROC_PRIMARY) {
mbuf_pool = pktmbuf_pool[qconf->socket_id];
mbuf_clone = rte_pktmbuf_clone(rtem, mbuf_pool);
mbuf_clone = pktmbuf_deep_clone(rtem, mbuf_pool);
if(mbuf_clone) {
ff_kni_enqueue(port_id, mbuf_clone);
}
}
ff_veth_input(ctx, rtem);
} else if (enable_kni && ((filter == FILTER_KNI && kni_accept) ||
} else if (enable_kni &&
((filter == FILTER_KNI && kni_accept) ||
(filter == FILTER_UNKNOWN && !kni_accept)) ) {
ff_kni_enqueue(port_id, rtem);
} else {