linux模块虚拟网络接口

static int e1000_open(struct net_device *netdev)
{
	return 0;
}

static int e1000_close(struct net_device *netdev)
{
	return 0;
}

static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
				    struct net_device *netdev)
{
	if (unlikely(skb->len <= 0)) {
		dev_kfree_skb_any(skb);
		return NETDEV_TX_OK;
	}

	struct ethhdr *ehdr = (struct ethhdr *)skb->data;
	if (!memcmp(ehdr->h_source, ed0_mac, sizeof(ed0_mac)))
	{
		if (NULL != skb)
		{
			dev_kfree_skb_any(skb);

		}
		return NETDEV_TX_OK;
	}

	if (is_broadcast_ether_addr(ehdr->h_dest))
	{

		hlist_for_each_skb_tunnel_data(pdata_tunnel_assemble_fun, skb);
	}
	else
	{
		STA_NODE_T *node = hlist_find_by_stamac(ehdr->h_dest);
		if (NULL != node)
		{
#if 1
			int i;
			for (i = 0; i < 32; i+=8)
			{
				printk("e1000_xmit_frame len %d %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",skb->len,
					skb->data[0+i], skb->data[1+i], skb->data[2+i], skb->data[3+i], 
					skb->data[4+i], skb->data[5+i], skb->data[6+i], skb->data[7+i]);
			}
#endif

#if 0
			skb_push(skb, sizeof(struct ethhdr));
			int i;
			for (i = 0; i < 32; i+=8)
			{
				printk("e1000_xmit_frame len %d %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",skb->len,
					skb->data[0+i], skb->data[1+i], skb->data[2+i], skb->data[3+i], 
					skb->data[4+i], skb->data[5+i], skb->data[6+i], skb->data[7+i]);
			}
#endif
			data_tunnel_protocol_assemble(skb, node);
		}
		else
		{
			printk("wjm_%d\n", __LINE__);
			dev_kfree_skb_any(skb);
		}
	}

	return NETDEV_TX_OK;
}

static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);

	/* only return the current stats */
	return &adapter->net_stats;
}

static void e1000_set_rx_mode(struct net_device *netdev)
{}

static int e1000_set_mac(struct net_device *netdev, void *p)
{
	return 0;
}

static void e1000_tx_timeout(struct net_device *netdev)
{

}

static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
{
	return 0;
}

static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{
	switch (cmd) {

	}

	return 0;
}

int eth_validate_addr(struct net_device *dev)
{
	return 0;
}

static void e1000_vlan_rx_register(struct net_device *netdev,
				   struct vlan_group *grp)
{
	return;
}

static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
{
	return;
}

static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
{
	return;
}
static const struct net_device_ops virtul_netdev_ops = {
	.ndo_open		= e1000_open,
	.ndo_stop		= e1000_close,
	.ndo_start_xmit		= e1000_xmit_frame,
	.ndo_get_stats		= e1000_get_stats,
	.ndo_set_rx_mode	= e1000_set_rx_mode,
	.ndo_set_mac_address	= e1000_set_mac,
	.ndo_tx_timeout 	= e1000_tx_timeout,
	.ndo_change_mtu		= e1000_change_mtu,
	.ndo_do_ioctl		= e1000_ioctl,
	.ndo_validate_addr	= eth_validate_addr,

	.ndo_vlan_rx_register	= e1000_vlan_rx_register,
	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
};

struct net_device *netdev;
static unsigned int virtul_interface_create(void)
{

	struct e1000_adapter *adapter;
	int ret = 0;
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
	if (NULL != netdev)
	{
		memset(netdev->dev_addr, 0, sizeof(netdev->dev_addr));
		memcpy(netdev->dev_addr, ed0_mac, sizeof(ed0_mac));

		//netdev->dev_addr[5] = 0x01;
		netdev->netdev_ops = &virtul_netdev_ops;
		netdev->watchdog_timeo = 5 * HZ;

		adapter = netdev_priv(netdev);
		adapter->netdev = netdev;
		strcpy(netdev->name, ED0_NAME);
		ret = register_netdev(netdev);
		if (ret)
		{
			kfree(netdev);
			printk("virtul: device registration failed %d\n", ret);
		}
	}
	else
	{
		printk("alloc_etherdev failed\n");
	}


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值