马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
一.网络装备驱动框架
接收
将报文从装备驱动接受并送入协议栈

老API netif_if
编写网络装备驱动
步调
1.注册一个网络装备
2.填充net_device_ops布局体
3.编写接收发送函数
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- * This module emits "Hello, world" on printk when loaded.
- *
- * It is designed to be used for basic evaluation of the module loading
- * subsystem (for example when validating module signing/verification). It
- * lacks any extra dependencies, and will not normally be loaded by the
- * system unless explicitly requested by name.
- */
- #include <linux/kernel.h>
- #include <linux/jiffies.h>
- #include <linux/module.h>
- #include <linux/interrupt.h>
- #include <linux/fs.h>
- #include <linux/types.h>
- #include <linux/string.h>
- #include <linux/socket.h>
- #include <linux/errno.h>
- #include <linux/fcntl.h>
- #include <linux/in.h>
- #include <linux/uaccess.h>
- #include <linux/io.h>
- #include <linux/inet.h>
- #include <linux/netdevice.h>
- #include <linux/etherdevice.h>
- #include <linux/skbuff.h>
- #include <linux/ethtool.h>
- #include <net/sock.h>
- #include <net/checksum.h>
- #include <linux/if_ether.h> /* For the statistics structure. */
- #include <linux/if_arp.h> /* For ARPHRD_ETHER */
- #include <linux/ip.h>
- #include <linux/tcp.h>
- #include <linux/percpu.h>
- #include <linux/net_tstamp.h>
- #include <net/net_namespace.h>
- #include <linux/u64_stats_sync.h>
- #include <linux/printk.h>
- #include <linux/icmp.h>
- #define DEBUG_TEST_NETDEV
- #define TEST_NETDEV_NAME "test%d"
- #define MAX_JUMBO_FRAME_SIZE 0x3F00
- static struct net_device *test_netdev;
- #ifdef DEBUG_TEST_NETDEV
- static void dump_skb (struct sk_buff * skb)
- {
- print_hex_dump(KERN_ERR, "data: ", DUMP_PREFIX_OFFSET,
- 16, 1, skb->data, skb->len, true);
- return;
- }
- #endif
- static int test_open(struct net_device *dev)
- {
- printk("<%s:%d>\n", __FUNCTION__,__LINE__);
- return 0;
- }
- static int test_close(struct net_device *dev)
- {
- printk("<%s:%d>\n", __FUNCTION__,__LINE__);
- return 0;
- }
- netdev_tx_t test_xmit_frame(struct sk_buff *skb, struct net_device *dev)
- {
- int len;
- struct ethhdr *ethh = eth_hdr(skb);
- struct iphdr *iph = ip_hdr(skb);
- struct icmphdr *icmph = icmp_hdr(skb);
- char mac_tmp[6];
- __be32 addr_tmp;
- printk("<%s:%d>\n", __FUNCTION__,__LINE__);
-
- #ifdef DEBUG_TEST_NETDEV
- dump_skb(skb);
- #endif
- memcpy(mac_tmp, ethh->h_source, 6);
- memcpy(ethh->h_source, ethh->h_dest, 6);
- memcpy(ethh->h_dest, mac_tmp, 6);
- addr_tmp = iph->saddr;
- iph->saddr = iph->daddr;
- iph->daddr = addr_tmp;
- icmph->type = 0;
- icmph->checksum = 0;
- icmph->checksum = ip_compute_csum(icmph, iph->tot_len - iph->ihl);
- iph->check = 0;
- iph->check = ip_compute_csum(iph, iph->tot_len);
-
- #ifdef DEBUG_TEST_NETDEV
- dump_skb(skb);
- #endif
- skb_tx_timestamp(skb);
- /* do not fool net_timestamp_check() with various clock bases */
- skb->tstamp = 0;
- skb_orphan(skb);
- /* Before queueing this packet to netif_rx(),
- * make sure dst is refcounted.
- */
- skb_dst_force(skb);
-
- skb->protocol = eth_type_trans(skb, dev);
- len = skb->len;
-
- if (likely(netif_rx(skb) == NET_RX_SUCCESS)) {
- test_netdev->stats.rx_bytes += len;
- test_netdev->stats.tx_bytes += len;
- test_netdev->stats.rx_packets++;
- test_netdev->stats.tx_packets++;
- }
-
- return NETDEV_TX_OK;
- }
- static void test_set_rx_mode(struct net_device *dev)
- {
- printk("<%s:%d>\n", __FUNCTION__,__LINE__);
- return;
- }
- static int test_set_mac(struct net_device *dev, void *addr)
- {
- struct sockaddr *saddr = addr;
- printk("<%s:%d> mac: %02x:%02x:%02x:%02x:%02x:%02x\n",__FUNCTION__,__LINE__,
- saddr->sa_data[0],saddr->sa_data[1],saddr->sa_data[2],saddr->sa_data[3],saddr->sa_data[4],saddr->sa_data[5]);
- memcpy(dev->dev_addr, saddr->sa_data, dev->addr_len);
- return 0;
- }
- static void test_tx_timeout (struct net_device *dev)
- {
- printk("<%s:%d>\n", __FUNCTION__,__LINE__);
- return;
- }
- static int test_change_mtu(struct net_device *dev, int new_mtu)
- {
- printk("<%s:%d>: mtu: %d\n", __FUNCTION__,__LINE__, new_mtu);
- return 0;
- }
- static int test_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
- {
- printk("<%s:%d> cmd %d\n", __FUNCTION__,__LINE__, cmd);
- return 0;
- }
- static void test_netpoll(struct net_device *dev)
- {
- printk("<%s:%d>\n", __FUNCTION__,__LINE__);
- return;
- }
- static netdev_features_t test_fix_features(struct net_device *dev, netdev_features_t features)
- {
-
- printk("<%s:%d> features %llx\n", __FUNCTION__,__LINE__, dev->features);
- return features;
- }
- static int test_set_features(struct net_device *dev, netdev_features_t features)
- {
- printk("<%s:%d> features %llx\n", __FUNCTION__,__LINE__, features);
- dev->features = features;
- return 1;
- }
- static void test_change_rx_flags(struct net_device *dev, int flags)
- {
- printk("<%s:%d> flags %d\n", __FUNCTION__,__LINE__, flags);
- }
- static const struct net_device_ops test_netdev_ops = {
- .ndo_open = test_open,
- .ndo_stop = test_close,
- .ndo_start_xmit = test_xmit_frame,
- .ndo_set_rx_mode = test_set_rx_mode,
- .ndo_set_mac_address = test_set_mac,
- .ndo_tx_timeout = test_tx_timeout,
- .ndo_change_mtu = test_change_mtu,
- .ndo_do_ioctl = test_ioctl,
- .ndo_validate_addr = eth_validate_addr,
- #ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = test_netpoll,
- #endif
- .ndo_fix_features = test_fix_features,
- .ndo_set_features = test_set_features,
- .ndo_change_rx_flags = test_change_rx_flags,
- };
- static int __init test_netdev_init(void)
- {
-
- int ret = 0;
- pr_warn("init test netdev\n");
- test_netdev = alloc_etherdev(sizeof(struct net_device));
- if (!test_netdev)
- goto out;
- test_netdev->netdev_ops = &test_netdev_ops;
- strcpy(test_netdev->name, TEST_NETDEV_NAME);
- ret = register_netdev(test_netdev);
- if(ret)
- goto failed;
- test_netdev->min_mtu = ETH_ZLEN - ETH_HLEN;
- test_netdev->max_mtu = MAX_JUMBO_FRAME_SIZE - (ETH_HLEN + ETH_FCS_LEN);
- memset(test_netdev->dev_addr, 0x60, test_netdev->addr_len);
- return 0;
- failed:
- free_netdev(test_netdev);
- out:
- return 0;
- }
- module_init(test_netdev_init);
- static void __exit test_netdev_exit(void)
- {
- pr_warn("exit test netdev\n");
- unregister_netdev(test_netdev);
- free_netdev(test_netdev);
- }
- module_exit(test_netdev_exit);
- MODULE_AUTHOR("Kees Cook <keescook@chromium.org>");
- MODULE_LICENSE("GPL");
复制代码 test0就是我们的驱动

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