-static inline void create_arp(struct rte_mbuf *mbuf, uint8_t *pkt_hdr, uint64_t *src_mac, uint32_t ip_dst, uint32_t ip_src)
-{
- uint64_t mac_bcast = 0xFFFFFFFFFFFF;
- rte_pktmbuf_pkt_len(mbuf) = 42;
- rte_pktmbuf_data_len(mbuf) = 42;
- init_mbuf_seg(mbuf);
- struct ether_hdr_arp *hdr_arp = (struct ether_hdr_arp *)pkt_hdr;
-
- memcpy(&hdr_arp->ether_hdr.d_addr.addr_bytes, &mac_bcast, 6);
- memcpy(&hdr_arp->ether_hdr.s_addr.addr_bytes, src_mac, 6);
- hdr_arp->ether_hdr.ether_type = ETYPE_ARP;
- hdr_arp->arp.htype = 0x100,
- hdr_arp->arp.ptype = 0x0008;
- hdr_arp->arp.hlen = 6;
- hdr_arp->arp.plen = 4;
- hdr_arp->arp.oper = 0x100;
- hdr_arp->arp.data.spa = ip_src;
- hdr_arp->arp.data.tpa = ip_dst;
- memset(&hdr_arp->arp.data.tha, 0, sizeof(struct ether_addr));
- memcpy(&hdr_arp->arp.data.sha, src_mac, sizeof(struct ether_addr));
-}
-
-static int task_gen_write_dst_mac(struct task_gen *task, struct rte_mbuf **mbufs, uint8_t **pkt_hdr, uint32_t count)
-{
- uint32_t ip_dst_pos, ip_src_pos, ip_dst, ip_src;
- uint16_t i;
- int ret;
-
- if (task->flags & FLAG_L3_GEN) {
- if (task->gw_ip) {
- if (unlikely((task->flags & FLAG_DST_MAC_KNOWN) == 0)) {
- for (i = 0; i < count; ++i) {
- struct pkt_template *pktpl = &task->pkt_template[mbufs[i]->udata64 & TEMPLATE_INDEX_MASK];
- create_arp(mbufs[i], pkt_hdr[i], (uint64_t *)&pktpl->buf[6], task->gw_ip, pktpl->ip_src);
- mbufs[i]->udata64 |= MBUF_ARP;
- }
- } else {
- for (i = 0; i < count; ++i) {
- struct ether_hdr *hdr = (struct ether_hdr *)pkt_hdr[i];
- memcpy(&hdr->d_addr.addr_bytes, &task->gw_mac, 6);
- }
- }
- } else if (unlikely((task->flags & FLAG_RANDOM_IPS) != 0) || (task->n_pkts >= 4)){
- // Find mac in lookup table. Send ARP if not found
- int32_t positions[MAX_PKT_BURST], idx;
- void *keys[MAX_PKT_BURST];
- uint32_t key[MAX_PKT_BURST];
- for (i = 0; i < count; ++i) {
- uint8_t *hdr = (uint8_t *)pkt_hdr[i];
- struct pkt_template *pktpl = &task->pkt_template[mbufs[i]->udata64 & TEMPLATE_INDEX_MASK];
- ip_dst_pos = pktpl->ip_dst_pos;
- ip_dst = *(uint32_t *)(hdr + ip_dst_pos);
- key[i] = ip_dst;
- keys[i] = &key[i];
- }
- ret = rte_hash_lookup_bulk(task->mac_hash, (const void **)&keys, count, positions);
- if (unlikely(ret < 0)) {
- plogx_err("lookup_bulk failed in mac_hash\n");
- tx_pkt_drop_all((struct task_base *)task, mbufs, count, NULL);
- return -1;
- }
- for (i = 0; i < count; ++i) {
- idx = positions[i];
- if (unlikely(idx < 0)) {
- // mac not found for this IP
- struct pkt_template *pktpl = &task->pkt_template[mbufs[i]->udata64 & TEMPLATE_INDEX_MASK];
- uint8_t *hdr = (uint8_t *)pkt_hdr[i];
- ip_src_pos = pktpl->ip_dst_pos - 4;
- ip_src = *(uint32_t *)(hdr + ip_src_pos);
- create_arp(mbufs[i], pkt_hdr[i], (uint64_t *)&hdr[6], key[i], ip_src);
- mbufs[i]->udata64 |= MBUF_ARP;
- } else {
- // mac found for this IP
- struct ether_hdr_arp *hdr_arp = (struct ether_hdr_arp *)pkt_hdr[i];
- memcpy(&hdr_arp->ether_hdr.d_addr.addr_bytes, &task->dst_mac[idx], 6);
- }
- }
- } else {
- for (i = 0; i < count; ++i) {
- uint8_t *hdr = (uint8_t *)pkt_hdr[i];
- struct pkt_template *pktpl = &task->pkt_template[mbufs[i]->udata64 & TEMPLATE_INDEX_MASK];
-
- // Check if packet template already has the mac
- if (unlikely(pktpl->dst_mac == 0)) {
- // no random_ip, can take from from packet template but no mac (yet)
- uint32_t ip_dst_pos = pktpl->ip_dst_pos;
- ip_dst = *(uint32_t *)(hdr + ip_dst_pos);
- create_arp(mbufs[i], pkt_hdr[i], (uint64_t *)&pktpl->buf[6], ip_dst, pktpl->ip_src);
- mbufs[i]->udata64 |= MBUF_ARP;
- } else {
- // no random ip, mac known
- struct ether_hdr_arp *hdr_arp = (struct ether_hdr_arp *)pkt_hdr[i];
- memcpy(&hdr_arp->ether_hdr.d_addr.addr_bytes, &pktpl->dst_mac, 6);
- }
- }
- }
- }
- return 0;
-}
-