Linux loopback NIC Driver Design, linux loopback NIC Driver

Source: Internet
Author: User

Linux loopback NIC Driver Design, linux loopback NIC Driver

Loop NIC Driver
1. The difference between a back-to-loop network card and a common network card is that it is virtual rather than a physical network card. It is equivalent to concatenating the sending end and the receiving end of the common network card.

2. in the kernel source code, the loopback Nic Program (drivers/net/loopback. c) It is not provided in the form of a module, but its initialization (loopback_net_init) and exit function (loopback_dev_free) will be called by other parts of the kernel.

3. follow the network card initialization flowchart to design the driver. The alloc_etherdev function cannot be used to allocate the net_device structure, because this function is assigned the structure of the Ethernet Card. Use the alloc_netdev function to assign a structure to the back-to-ring network card. Refer to how others use this function alloc_netdev (0, "lo", loopback_setup) in the kernel source code. The first 0 indicates the size of the private member of the net_device struct. Generally, select 0, the second is the name of the NIC, the name displayed by ifconfig, and the third is the initialization function pointer of the NIC struct.
Struct net_device * dev;
Dev = alloc_netdev (0, "lo", loopback_setup );
The loopback_setup function is called. (As for how to pass the form parameter when using the function pointer as a parameter, we need to review the C language)
4. hardware does not need to be initialized for the loopback Nic. Therefore, register the structure of the loopback Nic directly to the kernel (Step 3 ). Finally, specify the loopback Nic to register with the network subsystem.
Net-> loopback_dev = dev; this step is critical.

5. Specific initialization (loopback_setup) (step 2)
(1) The base address, MAC address, and interrupt number are not needed. It is mainly the structure of netdev_ops, which contains the operations supported by this Nic.

(2) indicates the maximum size of the packets that receive data supported by the loopback network interface card. In addition to the official data, there is also the header of the relevant network protocol.
Dev-> mtu = (16*1024) + 20 + 20 + 12; valid data is generally defined as 16 kb.

(3) Add the dedicated logo of the Back-to-ring network card.
Dev-> flags = IFF_LOOPBACK;
,
(4) In addition to the structure pointer of the header, the structure Pointer Points to a large number of function pointers that construct the Ethernet header.
Dev-> header_ops = & eth_header_ops;
Ideal search to see
Extern const struct header_ops eth_header_ops;

Struct header_ops {
Int (* create) (struct sk_buff * skb, struct net_device * dev,
Unsigned short type, const void * daddr,
Const void * saddr, unsigned len );
Int (* parse) (const struct sk_buff * skb, unsigned char * haddr );
Int (* rebuild) (struct sk_buff * skb );
# Define HAVE_HEADER_CACHE
Int (* cache) (const struct neighbor * neigh, struct hh_cache * hh );
Void (* cache_update) (struct hh_cache * hh,
Const struct net_device * dev,
Const unsigned char * haddr );
};
6. Data Transmission

Static int loopback_net_xmit (struct sk_buff * skb, struct net_device * dev)
{
Skb-> protocol = eth_type_trans (skb, dev );

Packets ++;
Bytes + = skb-> len;

Netif_rx (skb );

Return 0;
}


}
(1) The first parameter is the packet data transmitted from the protocol stack to the loopback Nic, and the second parameter is the structure of the loopback Nic.

(2) Stop the sending queue
The upper layer is notified to suspend sending data so that txd can send delivered data, but does not involve hardware. Therefore, you can ignore this issue on the loopback Nic. Correspondingly, you can ignore writing data into registers, waking up and sending again, and releasing the queue.

(3) Information Statistics, indicating the protocol of the package sent from the upper layer
Skb-> protocol = eth_type_trans (skb, dev );

(4) collect statistics on the size of data sent and the number of packages.

Bytes + = skb-> len;

Netif_rx (skb );


7. because data packets (skb) from the Protocol Stack are stored in txd, and txd does not need to be sent out, txd and rxd are connected together, therefore, the netif_rx (skb) function of the reception part of the common Nic is called directly in the sending part, so the receiving is completed at the same time. At the same time, we can clearly see that skb cannot be released at the time of sending; otherwise, no data can be received.

8. Function for obtaining the NIC status

Static struct net_device_stats * loopback_get_stats (struct net_device * dev)
{
Struct net_device_stats * stats = & dev-> stats;

Stats-> rx_packets = packets;
Stats-> tx_packets = packets;
Stats-> rx_bytes = bytes;
Stats-> tx_bytes = bytes;

Return stats;
}


Obtain the NIC status information from this struct.
/* The main device statistics structure */
Struct rtnl_link_stats64 {
_ U64 rx_packets;/* total packets received ed */
_ U64 tx_packets;/* total packets transmitted */
_ U64 rx_bytes;/* total bytes encoded ed */
_ U64 tx_bytes;/* total bytes transmitted */
_ U64 rx_errors;/* bad packets received */
_ U64 tx_errors;/* packet transmit problems */
_ U64 rx_dropped;/* no space in linux buffers */
_ U64 tx_dropped;/* no space available in linux */
_ U64 multicast;/* multicast packets received */
_ U64 collisions;

/* Detailed rx_errors :*/
_ U64 rx_length_errors;
_ U64 rx_over_errors;/* worker er ring buff overflow */
_ U64 rx_crc_errors;/* recved pkt with crc error */
_ U64 rx_frame_errors;/* recv 'd frame alignment error */
_ U64 rx_1_o_errors;/* recv 'r fifo overrun */
_ U64 rx_missed_errors;/* worker er missed packet */

/* Detailed tx_errors */
_ U64 tx_aborted_errors;
_ U64 tx_carrier_errors;
_ U64 tx_1_o_errors;
_ U64 tx_heartbeat_errors;
_ U64 tx_window_errors;

/* For cslip etc */
_ U64 rx_compressed;
_ U64 tx_compressed;
};
Mainly the four members
Stats-> rx_packets = packets;
Stats-> tx_packets = packets;
Stats-> rx_bytes = bytes;
Stats-> tx_bytes = bytes;
. In fact, you can override this function to get the status, because one of struct net_device * dev members is struct net_device_stats stats; therefore, during rewriting, you can define a struct net_device_stats pointing to the stats Member of the loop network card structure passed in by the form parameter. You only need to pay attention to the preceding four members of the stats member.

9. When you exit the driver, you cancel the registration of the struct. To log out of the network card.

Static _ net_exit void loopback_net_exit (struct net * net)
{
Struct net_device * dev = net-> loopback_dev;

Unregister_netdev (dev );
}

 

 

The sample code is as follows:

# 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/init. h>

# Include <asm/system. h>
# Include <asm/uaccess. h>
# Include <asm/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 <net/net_namespace.h>
# Include <linux/u64_stats_sync.h>

Unsigned long packets = 0;
Unsigned long bytes = 0;

// Struct net_device * dev;

Static _ net_exit void loopback_net_exit (struct net * net)
{
Struct net_device * dev = net-> loopback_dev;

Unregister_netdev (dev );
}


Static int loopback_net_xmit (struct sk_buff * skb, struct net_device * dev)
{
Skb-> protocol = eth_type_trans (skb, dev );

Packets ++;
Bytes + = skb-> len;

Netif_rx (skb );

Return 0;
}


Static struct net_device_stats * loopback_get_stats (struct net_device * dev)
{
Struct net_device_stats * stats = & dev-> stats;

Stats-> rx_packets = packets;
Stats-> tx_packets = packets;
Stats-> rx_bytes = bytes;
Stats-> tx_bytes = bytes;

Return stats;
}


Static const struct net_device_ops loopback_ops =
{
. Ndo_start_xmit = loopback_net_xmit,
. Ndo_get_stats = loopback_get_stats,
};


/*
* The loopback device is special. There is only one instance
* Per network namespace.
*/
Static void loopback_setup (struct net_device * dev)
{
Dev-> mtu = (16*1024) + 20 + 20 + 12;
Dev-> flags = IFF_LOOPBACK;
Dev-> header_ops = & eth_header_ops;
Dev-> netdev_ops = & loopback_ops;
}

/* Setup and register the loopback device .*/
Static int loopback_net_init (struct net * net)
{
Struct net_device * dev;
// 1.
Dev = alloc_netdev (0, "lo", loopback_setup );

// 4.
Register_netdev (dev );

Net-> loopback_dev = dev;

Return 0;
}

/* Registered in net/core/dev. c */
Struct pernet_operations _ net_initdata loopback_net_ops = {
. Init = loopback_net_init,
. Exit = loopback_net_exit,
};

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.