⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pktgen.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 3 页
字号:
		sprintf(info->result, "No memory");		return NULL;	}	skb_reserve(skb, 16);	/*  Reserve for ethernet and IP header  */	eth = (__u8 *) skb_push(skb, 14);	iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr));	udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));	/* Update any of the values, used when we're incrementing various	 * fields.	 */	mod_cur_headers(info);	memcpy(eth, info->hh, 14);		datalen = info->pkt_size - 14 - 20 - 8; /* Eth + IPh + UDPh */	if (datalen < sizeof(struct pktgen_hdr)) {		datalen = sizeof(struct pktgen_hdr);	}		udph->source = htons(info->cur_udp_src);	udph->dest = htons(info->cur_udp_dst);	udph->len = htons(datalen + 8); /* DATA + udphdr */	udph->check = 0;  /* No checksum */	iph->ihl = 5;	iph->version = 4;	iph->ttl = 3;	iph->tos = 0;	iph->protocol = IPPROTO_UDP; /* UDP */	iph->saddr = info->cur_saddr;	iph->daddr = info->cur_daddr;	iph->frag_off = 0;	iplen = 20 + 8 + datalen;	iph->tot_len = htons(iplen);	iph->check = 0;	iph->check = ip_fast_csum((void *) iph, iph->ihl);	skb->protocol = __constant_htons(ETH_P_IP);	skb->mac.raw = ((u8 *)iph) - 14;	skb->dev = odev;	skb->pkt_type = PACKET_HOST;	if (info->nfrags <= 0) {		pgh = (struct pktgen_hdr *)skb_put(skb, datalen);	} else {		int frags = info->nfrags;		int i;		/* TODO: Verify this is OK...it sure is ugly. --Ben */		pgh = (struct pktgen_hdr*)(((char*)(udph)) + 8);				if (frags > MAX_SKB_FRAGS)			frags = MAX_SKB_FRAGS;		if (datalen > frags*PAGE_SIZE) {			skb_put(skb, datalen-frags*PAGE_SIZE);			datalen = frags*PAGE_SIZE;		}		i = 0;		while (datalen > 0) {			struct page *page = alloc_pages(GFP_KERNEL, 0);			skb_shinfo(skb)->frags[i].page = page;			skb_shinfo(skb)->frags[i].page_offset = 0;			skb_shinfo(skb)->frags[i].size =				(datalen < PAGE_SIZE ? datalen : PAGE_SIZE);			datalen -= skb_shinfo(skb)->frags[i].size;			skb->len += skb_shinfo(skb)->frags[i].size;			skb->data_len += skb_shinfo(skb)->frags[i].size;			i++;			skb_shinfo(skb)->nr_frags = i;		}		while (i < frags) {			int rem;			if (i == 0)				break;			rem = skb_shinfo(skb)->frags[i - 1].size / 2;			if (rem == 0)				break;			skb_shinfo(skb)->frags[i - 1].size -= rem;			skb_shinfo(skb)->frags[i] = skb_shinfo(skb)->frags[i - 1];			get_page(skb_shinfo(skb)->frags[i].page);			skb_shinfo(skb)->frags[i].page = skb_shinfo(skb)->frags[i - 1].page;			skb_shinfo(skb)->frags[i].page_offset += skb_shinfo(skb)->frags[i - 1].size;			skb_shinfo(skb)->frags[i].size = rem;			i++;			skb_shinfo(skb)->nr_frags = i;		}	}	/* Stamp the time, and sequence number, convert them to network byte order */	if (pgh) {		struct timeval timestamp;		pgh->pgh_magic = htonl(PKTGEN_MAGIC);		pgh->seq_num   = htonl(info->seq_num);				do_gettimeofday(&timestamp);		pgh->tv_sec    = htonl(timestamp.tv_sec);		pgh->tv_usec   = htonl(timestamp.tv_usec);	}		return skb;}static void show_results(struct pktgen_info* info, int nr_frags){	__u64 total, bps, mbps, pps;	unsigned long idle;	int size = info->pkt_size + 4; /* incl 32bit ethernet CRC */	char *p = info->result;	total = (info->stopped_at.tv_sec - info->started_at.tv_sec) * 1000000ull		+ info->stopped_at.tv_usec - info->started_at.tv_usec;	BUG_ON(cpu_speed == 0);	idle = info->idle_acc;	do_div(idle, cpu_speed);	p += sprintf(p, "OK: %llu(c%llu+d%lu) usec, %llu (%dbyte,%dfrags)\n",		     total, total - idle, idle,		     info->sofar, size, nr_frags);	pps = info->sofar * USEC_PER_SEC;		while ((total >> 32) != 0) {		pps >>= 1;		total >>= 1;	}	do_div(pps, total);		bps = pps * 8 * size;	mbps = bps;	do_div(mbps, 1000000);	p += sprintf(p, "  %llupps %lluMb/sec (%llubps) errors: %llu",		     pps, mbps, bps, info->errors);}static void inject(struct pktgen_info* info){	struct net_device *odev;	struct sk_buff *skb = NULL;	__u64 lcount = 0;	int ret;	int last_ok = 1;	   /* Was last skb sent? 				    * Or a failed transmit of some sort?  This will keep				    * sequence numbers in order, for example.				    */	__u64 fp = 0;	__u32 fp_tmp = 0;	odev = setup_inject(info);	if (!odev)		return;	info->do_run_run = 1; /* Cranke yeself! */	info->idle_acc = 0;	info->sofar = 0;	lcount = info->count;	/* Build our initial pkt and place it as a re-try pkt. */	skb = fill_packet(odev, info);	if (skb == NULL) goto out_reldev;	do_gettimeofday(&(info->started_at));	while(info->do_run_run) {		/* Set a time-stamp, so build a new pkt each time */		if (last_ok) {			if (++fp_tmp >= info->clone_skb ) {				kfree_skb(skb);				skb = fill_packet(odev, info);				if (skb == NULL) {					goto out_reldev;				}				fp++;				fp_tmp = 0; /* reset counter */			}		}		if (!(odev->features & NETIF_F_LLTX))			spin_lock_bh(&odev->xmit_lock);		if (!netif_queue_stopped(odev)) {			atomic_inc(&skb->users);		retry:			ret = odev->hard_start_xmit(skb, odev);			if (likely(ret == NETDEV_TX_OK)) {				last_ok = 1;					info->sofar++;				info->seq_num++;			} else if (ret == NETDEV_TX_LOCKED 				   && (odev->features & NETIF_F_LLTX)) {				cpu_relax();				goto retry;			} else {				atomic_dec(&skb->users);				if (debug && net_ratelimit()) {				   printk(KERN_INFO "Hard xmit error\n");				}				info->errors++;				last_ok = 0;			}		}		else {			/* Re-try it next time */			last_ok = 0;		}				if (!(odev->features & NETIF_F_LLTX))			spin_unlock_bh(&odev->xmit_lock);		if (info->ipg) {			/* Try not to busy-spin if we have larger sleep times.			 * TODO:  Investigate better ways to do this.			 */			if (info->ipg < 10000) { /* 10 usecs or less */				nanospin(info->ipg, info);			}			else if (info->ipg < 10000000) { /* 10ms or less */				udelay(info->ipg / 1000);			}			else {				mdelay(info->ipg / 1000000);			}		}				if (signal_pending(current)) {			break;		}		/* If lcount is zero, then run forever */		if ((lcount != 0) && (--lcount == 0)) {			if (atomic_read(&skb->users) != 1) {				u32 idle_start, idle;				idle_start = cycles();				while (atomic_read(&skb->users) != 1) {					if (signal_pending(current)) {						break;					}					schedule();				}				idle = cycles() - idle_start;				info->idle_acc += idle;			}			break;		}		if (netif_queue_stopped(odev) || need_resched()) {			u32 idle_start, idle;			idle_start = cycles();			do {				if (signal_pending(current)) {					info->do_run_run = 0;					break;				}				if (!netif_running(odev)) {					info->do_run_run = 0;					break;				}				if (need_resched())					schedule();				else					do_softirq();			} while (netif_queue_stopped(odev));			idle = cycles() - idle_start;			info->idle_acc += idle;		}	}/* while we should be running */	do_gettimeofday(&(info->stopped_at));	show_results(info, skb_shinfo(skb)->nr_frags);	kfree_skb(skb);out_reldev:	if (odev) {		dev_put(odev);		odev = NULL;	}	return;}/* proc/net/pktgen/pg */static int proc_busy_read(char *buf , char **start, off_t offset,			     int len, int *eof, void *data){	char *p;	int idx = (int)(long)(data);	struct pktgen_info* info = NULL;		if ((idx < 0) || (idx >= MAX_PKTGEN)) {		printk("ERROR: idx: %i is out of range in proc_write\n", idx);		return -EINVAL;	}	info = &(pginfos[idx]);  	p = buf;	p += sprintf(p, "%d\n", info->busy);	*eof = 1;  	return p-buf;}static int proc_read(char *buf , char **start, off_t offset,			int len, int *eof, void *data){	char *p;	int i;	int idx = (int)(long)(data);	struct pktgen_info* info = NULL;	__u64 sa;	__u64 stopped;	__u64 now = getCurMs();		if ((idx < 0) || (idx >= MAX_PKTGEN)) {		printk("ERROR: idx: %i is out of range in proc_write\n", idx);		return -EINVAL;	}	info = &(pginfos[idx]);  	p = buf;	p += sprintf(p, "%s\n", VERSION); /* Help with parsing compatibility */	p += sprintf(p, "Params: count %llu  pkt_size: %u  frags: %d  ipg: %u  clone_skb: %d odev \"%s\"\n",		     (unsigned long long) info->count,		     info->pkt_size, info->nfrags, info->ipg,		     info->clone_skb, info->outdev);	p += sprintf(p, "     dst_min: %s  dst_max: %s  src_min: %s  src_max: %s\n",		     info->dst_min, info->dst_max, info->src_min, info->src_max);	p += sprintf(p, "     src_mac: ");	for (i = 0; i < 6; i++) {		p += sprintf(p, "%02X%s", info->src_mac[i], i == 5 ? "  " : ":");	}	p += sprintf(p, "dst_mac: ");	for (i = 0; i < 6; i++) {		p += sprintf(p, "%02X%s", info->dst_mac[i], i == 5 ? "\n" : ":");	}	p += sprintf(p, "     udp_src_min: %d  udp_src_max: %d  udp_dst_min: %d  udp_dst_max: %d\n",		     info->udp_src_min, info->udp_src_max, info->udp_dst_min,		     info->udp_dst_max);	p += sprintf(p, "     src_mac_count: %d  dst_mac_count: %d\n     Flags: ",		     info->src_mac_count, info->dst_mac_count);	if (info->flags &  F_IPSRC_RND) {		p += sprintf(p, "IPSRC_RND  ");	}	if (info->flags & F_IPDST_RND) {		p += sprintf(p, "IPDST_RND  ");	}	if (info->flags & F_UDPSRC_RND) {		p += sprintf(p, "UDPSRC_RND  ");	}	if (info->flags & F_UDPDST_RND) {		p += sprintf(p, "UDPDST_RND  ");	}	if (info->flags & F_MACSRC_RND) {		p += sprintf(p, "MACSRC_RND  ");	}	if (info->flags & F_MACDST_RND) {		p += sprintf(p, "MACDST_RND  ");	}	p += sprintf(p, "\n");		sa = tv_to_ms(&(info->started_at));	stopped = tv_to_ms(&(info->stopped_at));	if (info->do_run_run) {		stopped = now; /* not really stopped, more like last-running-at */	}	p += sprintf(p, "Current:\n     pkts-sofar: %llu  errors: %llu\n     started: %llums  stopped: %llums  now: %llums  idle: %lluns\n",		     (unsigned long long) info->sofar,		     (unsigned long long) info->errors,		     (unsigned long long) sa,		     (unsigned long long) stopped,		     (unsigned long long) now,		     (unsigned long long) info->idle_acc);	p += sprintf(p, "     seq_num: %d  cur_dst_mac_offset: %d  cur_src_mac_offset: %d\n",		     info->seq_num, info->cur_dst_mac_offset, info->cur_src_mac_offset);	p += sprintf(p, "     cur_saddr: 0x%x  cur_daddr: 0x%x  cur_udp_dst: %d  cur_udp_src: %d\n",		     info->cur_saddr, info->cur_daddr, info->cur_udp_dst, info->cur_udp_src);		if (info->result[0])		p += sprintf(p, "Result: %s\n", info->result);	else		p += sprintf(p, "Result: Idle\n");	*eof = 1;	return p - buf;}static int count_trail_chars(const char __user *user_buffer, unsigned int maxlen){	int i;	for (i = 0; i < maxlen; i++) {		char c;		if (get_user(c, &user_buffer[i]))			return -EFAULT;		switch (c) {		case '\"':		case '\n':		case '\r':		case '\t':		case ' ':		case '=':			break;		default:			goto done;		};	}done:	return i;}static unsigned long num_arg(const char __user *user_buffer, unsigned long maxlen,			     unsigned long *num){	int i = 0;	*num = 0;  	for(; i < maxlen; i++) {		char c;		if (get_user(c, &user_buffer[i]))			return -EFAULT;		if ((c >= '0') && (c <= '9')) {			*num *= 10;			*num += c -'0';		} else			break;	}	return i;}static int strn_len(const char __user *user_buffer, unsigned int maxlen){	int i = 0;	for(; i < maxlen; i++) {		char c;		if (get_user(c, &user_buffer[i]))			return -EFAULT;		switch (c) {		case '\"':		case '\n':		case '\r':		case '\t':		case ' ':			goto done_str;		default:			break;		};	}done_str:	return i;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -