Linux 网络装备驱动

饭宝  金牌会员 | 2024-8-13 20:11:44 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 576|帖子 576|积分 1728

一.网络装备驱动框架 

接收
将报文从装备驱动接受并送入协议栈

老API netif_if
编写网络装备驱动
步调
1.注册一个网络装备
2.填充net_device_ops布局体
3.编写接收发送函数
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * This module emits "Hello, world" on printk when loaded.
  4. *
  5. * It is designed to be used for basic evaluation of the module loading
  6. * subsystem (for example when validating module signing/verification). It
  7. * lacks any extra dependencies, and will not normally be loaded by the
  8. * system unless explicitly requested by name.
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/jiffies.h>
  12. #include <linux/module.h>
  13. #include <linux/interrupt.h>
  14. #include <linux/fs.h>
  15. #include <linux/types.h>
  16. #include <linux/string.h>
  17. #include <linux/socket.h>
  18. #include <linux/errno.h>
  19. #include <linux/fcntl.h>
  20. #include <linux/in.h>
  21. #include <linux/uaccess.h>
  22. #include <linux/io.h>
  23. #include <linux/inet.h>
  24. #include <linux/netdevice.h>
  25. #include <linux/etherdevice.h>
  26. #include <linux/skbuff.h>
  27. #include <linux/ethtool.h>
  28. #include <net/sock.h>
  29. #include <net/checksum.h>
  30. #include <linux/if_ether.h>        /* For the statistics structure. */
  31. #include <linux/if_arp.h>        /* For ARPHRD_ETHER */
  32. #include <linux/ip.h>
  33. #include <linux/tcp.h>
  34. #include <linux/percpu.h>
  35. #include <linux/net_tstamp.h>
  36. #include <net/net_namespace.h>
  37. #include <linux/u64_stats_sync.h>
  38. #include <linux/printk.h>
  39. #include <linux/icmp.h>
  40. #define DEBUG_TEST_NETDEV
  41. #define TEST_NETDEV_NAME "test%d"
  42. #define MAX_JUMBO_FRAME_SIZE         0x3F00
  43. static struct net_device *test_netdev;
  44. #ifdef DEBUG_TEST_NETDEV
  45. static void dump_skb (struct sk_buff * skb)
  46. {
  47.   print_hex_dump(KERN_ERR, "data: ", DUMP_PREFIX_OFFSET,
  48.                          16, 1, skb->data, skb->len, true);
  49.   return;
  50. }
  51. #endif
  52. static int test_open(struct net_device *dev)
  53. {
  54.         printk("<%s:%d>\n", __FUNCTION__,__LINE__);
  55.         return 0;
  56. }
  57. static int test_close(struct net_device *dev)
  58. {
  59.         printk("<%s:%d>\n", __FUNCTION__,__LINE__);
  60.         return 0;
  61. }
  62. netdev_tx_t        test_xmit_frame(struct sk_buff *skb, struct net_device *dev)
  63. {
  64.         int len;
  65.         struct ethhdr *ethh = eth_hdr(skb);
  66.         struct iphdr *iph = ip_hdr(skb);
  67.         struct icmphdr *icmph = icmp_hdr(skb);
  68.         char mac_tmp[6];
  69.         __be32 addr_tmp;
  70.         printk("<%s:%d>\n", __FUNCTION__,__LINE__);
  71.        
  72. #ifdef DEBUG_TEST_NETDEV
  73.         dump_skb(skb);
  74. #endif
  75.         memcpy(mac_tmp, ethh->h_source, 6);
  76.         memcpy(ethh->h_source, ethh->h_dest, 6);
  77.         memcpy(ethh->h_dest, mac_tmp, 6);
  78.         addr_tmp = iph->saddr;
  79.         iph->saddr = iph->daddr;
  80.         iph->daddr = addr_tmp;
  81.         icmph->type = 0;
  82.         icmph->checksum = 0;
  83.         icmph->checksum = ip_compute_csum(icmph, iph->tot_len - iph->ihl);
  84.         iph->check = 0;
  85.         iph->check = ip_compute_csum(iph, iph->tot_len);
  86.        
  87. #ifdef DEBUG_TEST_NETDEV
  88.         dump_skb(skb);
  89. #endif
  90.         skb_tx_timestamp(skb);
  91.         /* do not fool net_timestamp_check() with various clock bases */
  92.         skb->tstamp = 0;
  93.         skb_orphan(skb);
  94.         /* Before queueing this packet to netif_rx(),
  95.          * make sure dst is refcounted.
  96.          */
  97.         skb_dst_force(skb);
  98.        
  99.         skb->protocol = eth_type_trans(skb, dev);
  100.         len = skb->len;
  101.        
  102.         if (likely(netif_rx(skb) == NET_RX_SUCCESS)) {
  103.                 test_netdev->stats.rx_bytes += len;
  104.                 test_netdev->stats.tx_bytes += len;
  105.                 test_netdev->stats.rx_packets++;
  106.                 test_netdev->stats.tx_packets++;
  107.         }
  108.        
  109.         return NETDEV_TX_OK;
  110. }
  111. static void        test_set_rx_mode(struct net_device *dev)
  112. {
  113.         printk("<%s:%d>\n", __FUNCTION__,__LINE__);
  114.         return;
  115. }
  116. static int test_set_mac(struct net_device *dev, void *addr)
  117. {
  118.         struct sockaddr *saddr = addr;
  119.         printk("<%s:%d> mac: %02x:%02x:%02x:%02x:%02x:%02x\n",__FUNCTION__,__LINE__,
  120.                 saddr->sa_data[0],saddr->sa_data[1],saddr->sa_data[2],saddr->sa_data[3],saddr->sa_data[4],saddr->sa_data[5]);
  121.         memcpy(dev->dev_addr, saddr->sa_data, dev->addr_len);
  122.         return 0;
  123. }
  124. static void test_tx_timeout (struct net_device *dev)
  125. {
  126.         printk("<%s:%d>\n", __FUNCTION__,__LINE__);
  127.         return;
  128. }
  129. static int test_change_mtu(struct net_device *dev, int new_mtu)
  130. {
  131.         printk("<%s:%d>: mtu: %d\n", __FUNCTION__,__LINE__, new_mtu);
  132.         return 0;
  133. }
  134. static int test_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
  135. {
  136.         printk("<%s:%d> cmd %d\n", __FUNCTION__,__LINE__, cmd);
  137.         return 0;
  138. }
  139. static void test_netpoll(struct net_device *dev)
  140. {
  141.         printk("<%s:%d>\n", __FUNCTION__,__LINE__);
  142.         return;
  143. }
  144. static netdev_features_t test_fix_features(struct net_device *dev, netdev_features_t features)
  145. {
  146.        
  147.         printk("<%s:%d> features %llx\n", __FUNCTION__,__LINE__, dev->features);
  148.         return features;
  149. }
  150. static int test_set_features(struct net_device *dev, netdev_features_t features)
  151. {
  152.         printk("<%s:%d> features %llx\n", __FUNCTION__,__LINE__, features);
  153.         dev->features = features;
  154.         return 1;
  155. }
  156. static void test_change_rx_flags(struct net_device *dev, int flags)
  157. {
  158.         printk("<%s:%d> flags %d\n", __FUNCTION__,__LINE__, flags);
  159. }
  160. static const struct net_device_ops test_netdev_ops = {
  161.         .ndo_open                        = test_open,
  162.         .ndo_stop                        = test_close,
  163.         .ndo_start_xmit                = test_xmit_frame,
  164.         .ndo_set_rx_mode        = test_set_rx_mode,
  165.         .ndo_set_mac_address        = test_set_mac,
  166.         .ndo_tx_timeout                = test_tx_timeout,
  167.         .ndo_change_mtu                = test_change_mtu,
  168.         .ndo_do_ioctl                = test_ioctl,
  169.         .ndo_validate_addr        = eth_validate_addr,
  170. #ifdef CONFIG_NET_POLL_CONTROLLER
  171.         .ndo_poll_controller        = test_netpoll,
  172. #endif
  173.         .ndo_fix_features                = test_fix_features,
  174.         .ndo_set_features                = test_set_features,
  175.            .ndo_change_rx_flags         = test_change_rx_flags,
  176. };
  177. static int __init test_netdev_init(void)
  178. {
  179.        
  180.         int ret = 0;
  181.         pr_warn("init test netdev\n");
  182.         test_netdev = alloc_etherdev(sizeof(struct net_device));
  183.         if (!test_netdev)
  184.                 goto out;
  185.         test_netdev->netdev_ops = &test_netdev_ops;
  186.         strcpy(test_netdev->name, TEST_NETDEV_NAME);
  187.         ret = register_netdev(test_netdev);
  188.         if(ret)
  189.                 goto failed;
  190.         test_netdev->min_mtu = ETH_ZLEN - ETH_HLEN;
  191.         test_netdev->max_mtu = MAX_JUMBO_FRAME_SIZE - (ETH_HLEN + ETH_FCS_LEN);
  192.         memset(test_netdev->dev_addr, 0x60, test_netdev->addr_len);
  193.         return 0;
  194. failed:
  195.         free_netdev(test_netdev);
  196. out:
  197.         return 0;
  198. }
  199. module_init(test_netdev_init);
  200. static void __exit test_netdev_exit(void)
  201. {
  202.         pr_warn("exit test netdev\n");
  203.         unregister_netdev(test_netdev);
  204.         free_netdev(test_netdev);
  205. }
  206. module_exit(test_netdev_exit);
  207. MODULE_AUTHOR("Kees Cook <keescook@chromium.org>");
  208. MODULE_LICENSE("GPL");
复制代码
 test0就是我们的驱动


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

饭宝

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表