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模块虚拟网络接口
最新推荐文章于 2024-08-13 17:03:22 发布