linux模块虚拟网络接口
2013-09-11 18:03
435 查看
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"); } }
相关文章推荐
- linux虚拟网络接口 bond详解
- Linux虚拟网络接口 Bond详解
- Linux虚拟网络接口 Bond详解
- Linux运维笔记-文档总结-虚拟网络接口bond
- Linux 虚拟网络接口bond
- Linux 2.4.x 网络协议栈QoS模块(TC)的设计与实现(转)
- linux vmware player 虚拟网络配置
- linux虚拟网络设备以及namespace
- 第4章 Linux网络接口配置
- Linux 网络接口
- 基于Linux系统的Nagios网络管理模块的实现
- Linux 网卡驱动学习(二)(网络驱动接口小结)
- Linux企业级项目实践之网络爬虫(19)——epoll接口
- Linux网络配置之虚拟网卡的配置(ubuntu 16.04)
- linux的网络接口之扫盲
- 用c/c++实现linux下检测网络接口状态
- 2.4.16下网络结构全景图(包含模块接口变量名称)
- android--- Linux Proc虚拟文件系统—Android CPU、内存、网络流量获取
- 基于Linux系统的Nagios网络管理模块的实现