process netin ( int32 iface /* Interface for this process */ ) { struct ifentry *ifptr; /* ptr to interface table entry */ struct netpacket *pkt; /* ptr to current packet */ /* Do forever: read packets from the network and process */ ifptr = &if_tab[iface]; while(1) { /* Obtain next packet arriving on an interface */ wait(ifptr->if_sem); pkt = ifptr->if_queue[ifptr->if_head++]; if (ifptr->if_head >= IF_QUEUESIZE) { ifptr->if_head = 0; } /* Store interface number in packet buffer */ pkt->net_iface = iface; /* Convert Ethernet Type to host order */ eth_ntoh(pkt); /* Demultiplex on Ethernet type */ switch (pkt->net_ethtype) { case ETH_ARP: /* Handle ARP */ arp_in(iface,(struct arppacket *)pkt); continue; case ETH_IP: /* Handle IP */ ip_in(pkt); continue; case ETH_IPv6: /* Handle IPv6 */ freebuf((char *)pkt); continue; default: /* Ignore all other incoming packets */ freebuf((char *)pkt); continue; } } }
process netin () { struct netpacket *pkt; /* Ptr to current packet */ int32 retval; /* Return value from read */ /* Do forever: read a packet from the network and process */ while(1) { /* Allocate a buffer */ pkt = (struct netpacket *)getbuf(netbufpool); /* Obtain next packet that arrives */ retval = read(ETHER0, (char *)pkt, PACKLEN); if(retval == SYSERR) { panic("Cannot read from Ethernet\n"); } /* Convert Ethernet Type to host order */ eth_ntoh(pkt); /* Demultiplex on Ethernet type */ switch (pkt->net_ethtype) { case ETH_ARP: /* Handle ARP */ arp_in((struct arppacket *)pkt); continue; case ETH_IP: /* Handle IP */ ip_in(pkt); continue; case ETH_IPv6: /* Handle IPv6 */ freebuf((char *)pkt); continue; default: /* Ignore all other incoming packets */ freebuf((char *)pkt); continue; } } }
static void ether_in(struct lcore_env *env, struct rte_mbuf** bufs, unsigned n_rx, uint8_t src_port) { uint32_t j; for(j = 0; j < n_rx; j++) { int res = 0; int eth_type; struct rte_mbuf* pkt = bufs[j]; rte_prefetch0(rte_pktmbuf_mtod(pkt, void *)); struct ether_hdr *eth = rte_pktmbuf_mtod(pkt, struct ether_hdr *); eth_type = ntohs(eth->ether_type); //RTE_LOG(INFO, MARIO, "%s\n\tl2_len: %d\n\tl3_len:%d\n\tl4_len:%d\n", // __func__, pkt->l2_len, pkt->l3_len, pkt->l4_len); pkt->l2_len = ETHER_HDR_LEN; printf("eth_hdr_type : %x\n", eth->ether_type); printf("eth_type_arp : %x\n", ETHER_TYPE_ARP); switch (eth_type) { case ETHER_TYPE_ARP : { printf("arp recved\n"); print_eth(eth); res = arp_in(pkt); break; } case ETHER_TYPE_IPv4 : { printf("ip recved\n"); res = ip_in(pkt, src_port); //return value : port break; } case ETHER_TYPE_IPv6 : { ; break; } } // no need to send a packet. e.g. after receiving an arp_reply if(res < -1) continue; printf("send_packet\n"); send_packet(env, pkt, (res == -1) ? src_port : res); } }
int ether_in(struct rte_mbuf *mbuf) { struct ether_hdr *eth; eth = rte_pktmbuf_mtod(mbuf, struct ether_hdr *); switch(ntohs(eth->ether_type)) { case ETHER_TYPE_ARP : logger(ARP, NORMAL, "seen arp packet\n"); //printf("arp packet\n"); arp_in(mbuf); break; case ETHER_TYPE_IPv4 : logger(IP, NORMAL, "seen ip packet\n"); //printf("IP packet\n"); ip_in(mbuf); break; default : rte_pktmbuf_free(mbuf); } rte_pktmbuf_free(mbuf); // don't free here, future work. }