#include #include #include static void icmp_echo_request_entry(struct vdev_instance* vdi, queue_id_t sid, struct rte_mbuf * mbuf, struct in_addr s_in_addr, struct in_addr d_in_addr) { /* 将原来的报文复制一份 */ struct rte_mbuf * mbuf_cloned = rte_pktmbuf_alloc(vdi->direct_pool); char * _pkt_data = rte_pktmbuf_append(mbuf_cloned, rte_pktmbuf_data_len(mbuf)); rte_memcpy(_pkt_data, rte_pktmbuf_mtod(mbuf, char *), rte_pktmbuf_data_len(mbuf)); struct icmp_hdr * icmp_hdr = rte_pktmbuf_mtod_offset(mbuf_cloned, struct icmp_hdr *, sizeof(struct ether_hdr) + sizeof(struct ipv4_hdr)); uint32_t cksum; icmp_hdr->icmp_type = IP_ICMP_ECHO_REPLY; cksum = ~icmp_hdr->icmp_cksum & 0xffff; cksum += ~htons(IP_ICMP_ECHO_REQUEST << 8) & 0xffff; cksum += htons(IP_ICMP_ECHO_REPLY << 8); cksum = (cksum & 0xffff) + (cksum >> 16); cksum = (cksum & 0xffff) + (cksum >> 16); icmp_hdr->icmp_cksum = ~cksum; struct ipv4_hdr * ip_hdr = rte_pktmbuf_mtod_offset(mbuf_cloned, struct ipv4_hdr *, sizeof(struct ether_hdr)); ip_hdr->src_addr = d_in_addr.s_addr; ip_hdr->dst_addr = s_in_addr.s_addr; ip_hdr->hdr_checksum = 0; ip_hdr->hdr_checksum = rte_ipv4_cksum(ip_hdr); struct ether_addr ether_addr_swap; struct ether_hdr * eth_hdr = rte_pktmbuf_mtod(mbuf_cloned, struct ether_hdr *); ether_addr_copy(ð_hdr->s_addr, ðer_addr_swap); ether_addr_copy(ð_hdr->d_addr, ð_hdr->s_addr); ether_addr_copy(ðer_addr_swap, ð_hdr->d_addr); mrapp_packet_fast_send_burst(vdi, 0, &mbuf_cloned, 1); return; } int icmp_entry(struct mr_instance * instance, struct vdev_instance* vdi, queue_id_t qid, struct rte_mbuf* mbufs_in[], int nr_mbufs_in) { int handled_packets = 0; struct in_addr s_in_addr; struct in_addr d_in_addr; for (int i = 0; i < nr_mbufs_in; i++) { struct rte_mbuf * mbuf = mbufs_in[i]; if (unlikely(mbuf == NULL)) continue; // 仅处理IPv4报文 if (!RTE_ETH_IS_IPV4_HDR(mbuf->packet_type)) continue; // 校验IPv4报文类型 struct ipv4_hdr * ip_hdr = rte_pktmbuf_mtod_offset(mbuf, struct ipv4_hdr *, sizeof(struct ether_hdr)); if (ip_hdr->next_proto_id != IPPROTO_ICMP) continue; s_in_addr.s_addr = ip_hdr->src_addr; d_in_addr.s_addr = ip_hdr->dst_addr; struct icmp_hdr * icmp_hdr = rte_pktmbuf_mtod_offset(mbuf, struct icmp_hdr *, sizeof(struct ether_hdr) + sizeof(struct ipv4_hdr)); // ICMP回显请求,其他请求不处理 if (icmp_hdr->icmp_type == IP_ICMP_ECHO_REQUEST) { icmp_echo_request_entry(vdi, qid, mbuf, s_in_addr, d_in_addr); } handled_packets++; } return handled_packets; }