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

📄 netpoll.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 2 页
字号:
	 */	arp->ar_hrd = htons(np->dev->type);	arp->ar_pro = htons(ETH_P_IP);	arp->ar_hln = np->dev->addr_len;	arp->ar_pln = 4;	arp->ar_op = htons(type);	arp_ptr=(unsigned char *)(arp + 1);	memcpy(arp_ptr, np->dev->dev_addr, np->dev->addr_len);	arp_ptr += np->dev->addr_len;	memcpy(arp_ptr, &tip, 4);	arp_ptr += 4;	memcpy(arp_ptr, np->remote_mac, np->dev->addr_len);	arp_ptr += np->dev->addr_len;	memcpy(arp_ptr, &sip, 4);	netpoll_send_skb(np, send_skb);}int netpoll_rx(struct sk_buff *skb){	int proto, len, ulen;	struct iphdr *iph;	struct udphdr *uh;	struct netpoll *np;	struct list_head *p;	unsigned long flags;	if (skb->dev->type != ARPHRD_ETHER)		goto out;	/* check if netpoll clients need ARP */	if (skb->protocol == __constant_htons(ETH_P_ARP) &&	    atomic_read(&trapped)) {		arp_reply(skb);		return 1;	}	proto = ntohs(eth_hdr(skb)->h_proto);	if (proto != ETH_P_IP)		goto out;	if (skb->pkt_type == PACKET_OTHERHOST)		goto out;	if (skb_shared(skb))		goto out;	iph = (struct iphdr *)skb->data;	if (!pskb_may_pull(skb, sizeof(struct iphdr)))		goto out;	if (iph->ihl < 5 || iph->version != 4)		goto out;	if (!pskb_may_pull(skb, iph->ihl*4))		goto out;	if (ip_fast_csum((u8 *)iph, iph->ihl) != 0)		goto out;	len = ntohs(iph->tot_len);	if (skb->len < len || len < iph->ihl*4)		goto out;	if (iph->protocol != IPPROTO_UDP)		goto out;	len -= iph->ihl*4;	uh = (struct udphdr *)(((char *)iph) + iph->ihl*4);	ulen = ntohs(uh->len);	if (ulen != len)		goto out;	if (checksum_udp(skb, uh, ulen, iph->saddr, iph->daddr) < 0)		goto out;	spin_lock_irqsave(&rx_list_lock, flags);	list_for_each(p, &rx_list) {		np = list_entry(p, struct netpoll, rx_list);		if (np->dev && np->dev != skb->dev)			continue;		if (np->local_ip && np->local_ip != ntohl(iph->daddr))			continue;		if (np->remote_ip && np->remote_ip != ntohl(iph->saddr))			continue;		if (np->local_port && np->local_port != ntohs(uh->dest))			continue;		spin_unlock_irqrestore(&rx_list_lock, flags);		if (np->rx_hook)			np->rx_hook(np, ntohs(uh->source),				    (char *)(uh+1),				    ulen - sizeof(struct udphdr));		return 1;	}	spin_unlock_irqrestore(&rx_list_lock, flags);out:	return atomic_read(&trapped);}int netpoll_parse_options(struct netpoll *np, char *opt){	char *cur=opt, *delim;	if(*cur != '@') {		if ((delim = strchr(cur, '@')) == NULL)			goto parse_failed;		*delim=0;		np->local_port=simple_strtol(cur, NULL, 10);		cur=delim;	}	cur++;	printk(KERN_INFO "%s: local port %d\n", np->name, np->local_port);	if(*cur != '/') {		if ((delim = strchr(cur, '/')) == NULL)			goto parse_failed;		*delim=0;		np->local_ip=ntohl(in_aton(cur));		cur=delim;		printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n",		       np->name, HIPQUAD(np->local_ip));	}	cur++;	if ( *cur != ',') {		/* parse out dev name */		if ((delim = strchr(cur, ',')) == NULL)			goto parse_failed;		*delim=0;		strlcpy(np->dev_name, cur, sizeof(np->dev_name));		cur=delim;	}	cur++;	printk(KERN_INFO "%s: interface %s\n", np->name, np->dev_name);	if ( *cur != '@' ) {		/* dst port */		if ((delim = strchr(cur, '@')) == NULL)			goto parse_failed;		*delim=0;		np->remote_port=simple_strtol(cur, NULL, 10);		cur=delim;	}	cur++;	printk(KERN_INFO "%s: remote port %d\n", np->name, np->remote_port);	/* dst ip */	if ((delim = strchr(cur, '/')) == NULL)		goto parse_failed;	*delim=0;	np->remote_ip=ntohl(in_aton(cur));	cur=delim+1;	printk(KERN_INFO "%s: remote IP %d.%d.%d.%d\n",		       np->name, HIPQUAD(np->remote_ip));	if( *cur != 0 )	{		/* MAC address */		if ((delim = strchr(cur, ':')) == NULL)			goto parse_failed;		*delim=0;		np->remote_mac[0]=simple_strtol(cur, NULL, 16);		cur=delim+1;		if ((delim = strchr(cur, ':')) == NULL)			goto parse_failed;		*delim=0;		np->remote_mac[1]=simple_strtol(cur, NULL, 16);		cur=delim+1;		if ((delim = strchr(cur, ':')) == NULL)			goto parse_failed;		*delim=0;		np->remote_mac[2]=simple_strtol(cur, NULL, 16);		cur=delim+1;		if ((delim = strchr(cur, ':')) == NULL)			goto parse_failed;		*delim=0;		np->remote_mac[3]=simple_strtol(cur, NULL, 16);		cur=delim+1;		if ((delim = strchr(cur, ':')) == NULL)			goto parse_failed;		*delim=0;		np->remote_mac[4]=simple_strtol(cur, NULL, 16);		cur=delim+1;		np->remote_mac[5]=simple_strtol(cur, NULL, 16);	}	printk(KERN_INFO "%s: remote ethernet address "	       "%02x:%02x:%02x:%02x:%02x:%02x\n",	       np->name,	       np->remote_mac[0],	       np->remote_mac[1],	       np->remote_mac[2],	       np->remote_mac[3],	       np->remote_mac[4],	       np->remote_mac[5]);	return 0; parse_failed:	printk(KERN_INFO "%s: couldn't parse config at %s!\n",	       np->name, cur);	return -1;}int netpoll_setup(struct netpoll *np){	struct net_device *ndev = NULL;	struct in_device *in_dev;	if (np->dev_name)		ndev = dev_get_by_name(np->dev_name);	if (!ndev) {		printk(KERN_ERR "%s: %s doesn't exist, aborting.\n",		       np->name, np->dev_name);		return -1;	}	if (!ndev->poll_controller) {		printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n",		       np->name, np->dev_name);		goto release;	}	if (!(ndev->flags & IFF_UP)) {		unsigned short oflags;		unsigned long atmost, atleast;		printk(KERN_INFO "%s: device %s not up yet, forcing it\n",		       np->name, np->dev_name);		oflags = ndev->flags;		rtnl_shlock();		if (dev_change_flags(ndev, oflags | IFF_UP) < 0) {			printk(KERN_ERR "%s: failed to open %s\n",			       np->name, np->dev_name);			rtnl_shunlock();			goto release;		}		rtnl_shunlock();		atleast = jiffies + HZ/10; 		atmost = jiffies + 10*HZ;		while (!netif_carrier_ok(ndev)) {			if (time_after(jiffies, atmost)) {				printk(KERN_NOTICE				       "%s: timeout waiting for carrier\n",				       np->name);				break;			}			cond_resched();		}		if (time_before(jiffies, atleast)) {			printk(KERN_NOTICE "%s: carrier detect appears flaky,"			       " waiting 10 seconds\n",			       np->name);			while (time_before(jiffies, atmost))				cond_resched();		}	}	if (!memcmp(np->local_mac, "\0\0\0\0\0\0", 6) && ndev->dev_addr)		memcpy(np->local_mac, ndev->dev_addr, 6);	if (!np->local_ip) {		rcu_read_lock();		in_dev = __in_dev_get(ndev);		if (!in_dev) {			rcu_read_unlock();			printk(KERN_ERR "%s: no IP address for %s, aborting\n",			       np->name, np->dev_name);			goto release;		}		np->local_ip = ntohl(in_dev->ifa_list->ifa_local);		rcu_read_unlock();		printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n",		       np->name, HIPQUAD(np->local_ip));	}	np->dev = ndev;	if(np->rx_hook) {		unsigned long flags;		np->dev->netpoll_rx = NETPOLL_RX_ENABLED;		spin_lock_irqsave(&rx_list_lock, flags);		list_add(&np->rx_list, &rx_list);		spin_unlock_irqrestore(&rx_list_lock, flags);	}	return 0; release:	dev_put(ndev);	return -1;}void netpoll_cleanup(struct netpoll *np){	if (np->rx_hook) {		unsigned long flags;		spin_lock_irqsave(&rx_list_lock, flags);		list_del(&np->rx_list);		spin_unlock_irqrestore(&rx_list_lock, flags);	}	if (np->dev)		np->dev->netpoll_rx = 0;	dev_put(np->dev);	np->dev = NULL;}int netpoll_trap(void){	return atomic_read(&trapped);}void netpoll_set_trap(int trap){	if (trap)		atomic_inc(&trapped);	else		atomic_dec(&trapped);}EXPORT_SYMBOL(netpoll_set_trap);EXPORT_SYMBOL(netpoll_trap);EXPORT_SYMBOL(netpoll_parse_options);EXPORT_SYMBOL(netpoll_setup);EXPORT_SYMBOL(netpoll_cleanup);EXPORT_SYMBOL(netpoll_send_skb);EXPORT_SYMBOL(netpoll_send_udp);EXPORT_SYMBOL(netpoll_poll);

⌨️ 快捷键说明

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