Exemplo n.º 1
0
static int rx_thread(void * param) {
	struct port_configure * pconf = NULL; //(struct port_configure *) param;
	struct rte_ring* ring_in = NULL; //pconf->ring_in;
	struct rte_ring* ring_out = NULL; //pconf->ring_out;
	uint8_t port_id = 0; //pconf->portid;
	uint16_t nb_rx_pkts;
	struct rte_mbuf *m;
	struct ether_hdr *eth_hdr;
	struct arp_hdr *arp_hdr;
	int32_t i, j, k, ret;
	struct rte_mbuf *pkts[MAX_PKTS_BURST];
	int32_t ether_type;
	struct ipv4_hdr *ip_hdr;
	struct icmp_hdr* icmp_hdr;
	struct udp_hdr* udp_hdr;

	while (!quit_signal) {
		for (k = 0; k < num_config_port; ++k) {
			pconf = &ports_conf[k];
			ring_in = pconf->ring_in;
			ring_out = pconf->ring_out;
			port_id = pconf->portid;

			nb_rx_pkts = rte_eth_rx_burst(port_id, 0, pkts, MAX_PKTS_BURST);

			if (unlikely(nb_rx_pkts == 0)) {
				continue;
			}

			for (i = 0; i < nb_rx_pkts; ++i) {
				m = pkts[i];
				eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
				ether_type = eth_hdr->ether_type;

				if (unlikely(rte_cpu_to_be_16(ETHER_TYPE_ARP) == ether_type)) {

					arp_hdr = (struct arp_hdr *) ((char *) (eth_hdr + 1));

					if (arp_hdr->arp_op == rte_cpu_to_be_16(ARP_OP_REQUEST)) {
						if (arp_hdr->arp_data.arp_tip == (pconf->ip)) {
							arp_hdr->arp_op = rte_cpu_to_be_16(ARP_OP_REPLY);
							ether_addr_copy(&eth_hdr->s_addr, &eth_hdr->d_addr);
							ether_addr_copy(&pconf->addr, &eth_hdr->s_addr);
							ether_addr_copy(&arp_hdr->arp_data.arp_sha,
									&arp_hdr->arp_data.arp_tha);
							arp_hdr->arp_data.arp_tip =
									arp_hdr->arp_data.arp_sip;
							ether_addr_copy(&pconf->addr,
									&arp_hdr->arp_data.arp_sha);
							arp_hdr->arp_data.arp_sip = (pconf->ip);
							MMENQUEUE(ring_out, m);
						} else {
							MMENQUEUE(ring_arp_request, m);
						}
					} else if (arp_hdr->arp_op == rte_cpu_to_be_16(ARP_OP_REPLY)) {
						MMENQUEUE(ring_arp_reply, m);
					} else {
						rte_pktmbuf_free(m);
					}
				} else if (likely(
						rte_cpu_to_be_16(ETHER_TYPE_IPv4) == ether_type)) {
					ip_hdr = (struct ipv4_hdr *) ((char *) (eth_hdr + 1));
					switch (ip_hdr->next_proto_id) {
					case IPPROTO_ICMP:
						//printf("nhan ban tin ping\n");
						icmp_hdr = (struct icmp_hdr *) ((unsigned char *) ip_hdr
								+ sizeof(struct ipv4_hdr));

						if (unlikely(
								wrapsum(
										checksum(icmp_hdr,
												(m->data_len
														- sizeof(struct ether_hdr)
														- sizeof(struct ipv4_hdr)),
												0)))) {
							printf("ICMP check sum error\n");
							rte_pktmbuf_free(m);
							break;
						}

						if (unlikely(
								icmp_hdr->icmp_type == IP_ICMP_ECHO_REQUEST)) {
							if (ntohl(ip_hdr->dst_addr) == INADDR_BROADCAST) {
								rte_pktmbuf_free(m);
							} else {
								icmp_hdr->icmp_type = IP_ICMP_ECHO_REPLY;
								icmp_hdr->icmp_cksum = 0;
								icmp_hdr->icmp_cksum =
										wrapsum(
												checksum(icmp_hdr,
														(m->data_len
																- sizeof(struct ether_hdr)
																- sizeof(struct ipv4_hdr)),
														0));

								inetAddrSwap(&ip_hdr->src_addr,
										&ip_hdr->dst_addr);

								ip_hdr->packet_id = htons(
										ntohs(ip_hdr->packet_id) + m->data_len);

								ip_hdr->hdr_checksum = 0;
								ip_hdr->hdr_checksum = wrapsum(
										checksum(ip_hdr,
												sizeof(struct ipv4_hdr), 0));

								ethAddrSwap(&eth_hdr->d_addr, &eth_hdr->s_addr);
								MMENQUEUE(ring_out, m);
							}
						} else {
							rte_pktmbuf_free(m);
						}
						break;
					case IPPROTO_UDP:
						MMENQUEUE(ring_in, m)
						;
						break;

					default:
						rte_pktmbuf_free(m);
					}

				} else {
					rte_pktmbuf_free(m);
				}
			}
		}
	}

	return 0;
}
Exemplo n.º 2
0
void
pktgen_process_arp( struct rte_mbuf * m, uint32_t pid, uint32_t vlan )
{
    port_info_t   * info = &pktgen.info[pid];
    pkt_seq_t     * pkt;
    struct ether_hdr *eth = rte_pktmbuf_mtod(m, struct ether_hdr *);
    arpPkt_t      * arp = (arpPkt_t *)&eth[1];

	/* Adjust for a vlan header if present */
	if ( vlan )
		arp = (arpPkt_t *)((char *)arp + sizeof(struct vlan_hdr));

    // Process all ARP requests if they are for us.
    if ( arp->op == htons(ARP_REQUEST) ) {
		if ((rte_atomic32_read(&info->port_flags) & PROCESS_GARP_PKTS) &&
 			(arp->tpa._32 == arp->spa._32) ) {		/* Must be a GARP packet */

			pkt = pktgen_find_matching_ipdst(info, arp->spa._32);

			/* Found a matching packet, replace the dst address */
			if ( pkt ) {
				rte_memcpy(&pkt->eth_dst_addr, &arp->sha, 6);
				pktgen_set_q_flags(info, wr_get_txque(pktgen.l2p, rte_lcore_id(), pid), DO_TX_CLEANUP);
				pktgen_redisplay(0);
			}
			return;
		}

		pkt = pktgen_find_matching_ipsrc(info, arp->tpa._32);

		/* ARP request not for this interface. */
		if ( likely(pkt != NULL) ) {
			/* Grab the source MAC address as the destination address for the port. */
			if ( unlikely(pktgen.flags & MAC_FROM_ARP_FLAG) ) {
				uint32_t    i;

				rte_memcpy(&pkt->eth_dst_addr, &arp->sha, 6);
				for (i = 0; i < info->seqCnt; i++)
					pktgen_packet_ctor(info, i, -1);
			}

			// Swap the two MAC addresses
			ethAddrSwap(&arp->sha, &arp->tha);

			// Swap the two IP addresses
			inetAddrSwap(&arp->tpa._32, &arp->spa._32);

			// Set the packet to ARP reply
			arp->op = htons(ARP_REPLY);

			// Swap the MAC addresses
			ethAddrSwap(&eth->d_addr, &eth->s_addr);

			// Copy in the MAC address for the reply.
			rte_memcpy(&arp->sha, &pkt->eth_src_addr, 6);
			rte_memcpy(&eth->s_addr, &pkt->eth_src_addr, 6);

			pktgen_send_mbuf(m, pid, 0);

			// Flush all of the packets in the queue.
			pktgen_set_q_flags(info, 0, DO_TX_FLUSH);

			// No need to free mbuf as it was reused
			return;
		}
	} else if ( arp->op == htons(ARP_REPLY) ) {
		pkt = pktgen_find_matching_ipsrc(info, arp->tpa._32);

		// ARP request not for this interface.
		if ( likely(pkt != NULL) ) {
			// Grab the real destination MAC address
			if ( pkt->ip_dst_addr == ntohl(arp->spa._32) )
				rte_memcpy(&pkt->eth_dst_addr, &arp->sha, 6);

			pktgen.flags |= PRINT_LABELS_FLAG;
		}
	}
}
Exemplo n.º 3
0
void
pktgen_process_ping4( struct rte_mbuf * m, uint32_t pid, uint32_t vlan )
{
    port_info_t   * info = &pktgen.info[pid];
    pkt_seq_t     * pkt;
    struct ether_hdr *eth = rte_pktmbuf_mtod(m, struct ether_hdr *);
    ipHdr_t       * ip = (ipHdr_t *)&eth[1];
    char            buff[24];

	/* Adjust for a vlan header if present */
	if ( vlan )
		ip = (ipHdr_t *)((char *)ip + sizeof(struct vlan_hdr));

    // Look for a ICMP echo requests, but only if enabled.
    if ( (rte_atomic32_read(&info->port_flags) & ICMP_ECHO_ENABLE_FLAG) &&
    		(ip->proto == PG_IPPROTO_ICMP) ) {
#if !defined(RTE_ARCH_X86_64)
        icmpv4Hdr_t * icmp = (icmpv4Hdr_t *)((uint32_t)ip + sizeof(ipHdr_t));
#else
        icmpv4Hdr_t * icmp = (icmpv4Hdr_t *)((uint64_t)ip + sizeof(ipHdr_t));
#endif

        // We do not handle IP options, which will effect the IP header size.
        if ( unlikely(cksum(icmp, (m->data_len - sizeof(struct ether_hdr) - sizeof(ipHdr_t)), 0)) ) {
            pktgen_log_error("ICMP checksum failed");
            return;
        }

        if ( unlikely(icmp->type == ICMP4_ECHO) ) {
            if ( ntohl(ip->dst) == INADDR_BROADCAST ) {
                pktgen_log_warning("IP address %s is a Broadcast",
                        inet_ntop4(buff, sizeof(buff), ip->dst, INADDR_BROADCAST));
                return;
            }

            // Toss all broadcast addresses and requests not for this port
            pkt = pktgen_find_matching_ipsrc(info, ip->dst);

            // ARP request not for this interface.
            if ( unlikely(pkt == NULL) ) {
                pktgen_log_warning("IP address %s not found",
                        inet_ntop4(buff, sizeof(buff), ip->dst, INADDR_BROADCAST));
                return;
            }

            info->stats.echo_pkts++;

            icmp->type  = ICMP4_ECHO_REPLY;

            /* Recompute the ICMP checksum */
            icmp->cksum = 0;
            icmp->cksum = cksum(icmp, (m->data_len - sizeof(struct ether_hdr) - sizeof(ipHdr_t)), 0);

            // Swap the IP addresses.
            inetAddrSwap(&ip->src, &ip->dst);

            // Bump the ident value
            ip->ident   = htons(ntohs(ip->ident) + m->data_len);

            // Recompute the IP checksum
            ip->cksum   = 0;
            ip->cksum   = cksum(ip, sizeof(ipHdr_t), 0);

            // Swap the MAC addresses
            ethAddrSwap(&eth->d_addr, &eth->s_addr);

            pktgen_send_mbuf(m, pid, 0);

            pktgen_set_q_flags(info, 0, DO_TX_FLUSH);

            // No need to free mbuf as it was reused.
            return;
        } else if ( unlikely(icmp->type == ICMP4_ECHO_REPLY) ) {
            info->stats.echo_pkts++;
        }
    }
}