static void process_ipv4(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt) { /* Assume there is no ethernet header */ struct ipv4_hdr *pkt_hdr = rte_pktmbuf_mtod(pkt, struct ipv4_hdr *); /* Get "More fragments" flag and fragment offset */ uint16_t frag_field = rte_be_to_cpu_16(pkt_hdr->fragment_offset); uint16_t frag_offset = (uint16_t)(frag_field & IPV4_HDR_OFFSET_MASK); uint16_t frag_flag = (uint16_t)(frag_field & IPV4_HDR_MF_FLAG); /* If it is a fragmented packet, then try to reassemble */ if ((frag_flag == 0) && (frag_offset == 0)) p->tx_buf[p->tx_buf_count++] = pkt; else { struct rte_mbuf *mo; struct rte_ip_frag_tbl *tbl = p->frag_tbl; struct rte_ip_frag_death_row *dr = &p->death_row; pkt->l3_len = sizeof(*pkt_hdr); /* Process this fragment */ mo = rte_ipv4_frag_reassemble_packet(tbl, dr, pkt, rte_rdtsc(), pkt_hdr); if (mo != NULL) p->tx_buf[p->tx_buf_count++] = mo; rte_ip_frag_free_death_row(&p->death_row, 3); } }
struct rte_mbuf * ipv4_reassemble(lcore_conf_t *qconf, struct rte_mbuf *m, struct ether_hdr **eth_hdr_pp, struct ipv4_hdr **ip_hdr_pp) { struct ipv4_hdr *ip_hdr = *ip_hdr_pp; struct rte_ip_frag_tbl *tbl; struct rte_ip_frag_death_row *dr; /* if it is a fragmented packet, then try to reassemble. */ if (rte_ipv4_frag_pkt_is_fragmented(ip_hdr)) { struct rte_mbuf *mo; tbl = qconf->frag_tbl; dr = &qconf->death_row; /* process this fragment. */ mo = rte_ipv4_frag_reassemble_packet(tbl, dr, m, rte_rdtsc(), ip_hdr); if (mo == NULL) /* no packet to send out. */ return NULL; /* we have our packet reassembled. */ if (mo != m) { m = mo; *eth_hdr_pp = rte_pktmbuf_mtod(m, struct ether_hdr *); *ip_hdr_pp = (struct ipv4_hdr *)(*eth_hdr_pp + 1); } }