Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * INET     An implementation of the TCP/IP protocol suite for the LINUX
0004  *      operating system.  INET is implemented using the  BSD Socket
0005  *      interface as the means of communication with the user level.
0006  *
0007  *      Pseudo-driver for the loopback interface.
0008  *
0009  * Version: @(#)loopback.c  1.0.4b  08/16/93
0010  *
0011  * Authors: Ross Biro
0012  *      Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
0013  *      Donald Becker, <becker@scyld.com>
0014  *
0015  *      Alan Cox    :   Fixed oddments for NET3.014
0016  *      Alan Cox    :   Rejig for NET3.029 snap #3
0017  *      Alan Cox    :   Fixed NET3.029 bugs and sped up
0018  *      Larry McVoy :   Tiny tweak to double performance
0019  *      Alan Cox    :   Backed out LMV's tweak - the linux mm
0020  *                  can't take it...
0021  *              Michael Griffith:       Don't bother computing the checksums
0022  *                                      on packets received on the loopback
0023  *                                      interface.
0024  *      Alexey Kuznetsov:   Potential hang under some extreme
0025  *                  cases removed.
0026  */
0027 #include <linux/kernel.h>
0028 #include <linux/jiffies.h>
0029 #include <linux/module.h>
0030 #include <linux/interrupt.h>
0031 #include <linux/fs.h>
0032 #include <linux/types.h>
0033 #include <linux/string.h>
0034 #include <linux/socket.h>
0035 #include <linux/errno.h>
0036 #include <linux/fcntl.h>
0037 #include <linux/in.h>
0038 
0039 #include <linux/uaccess.h>
0040 #include <linux/io.h>
0041 
0042 #include <linux/inet.h>
0043 #include <linux/netdevice.h>
0044 #include <linux/etherdevice.h>
0045 #include <linux/skbuff.h>
0046 #include <linux/ethtool.h>
0047 #include <net/sch_generic.h>
0048 #include <net/sock.h>
0049 #include <net/checksum.h>
0050 #include <linux/if_ether.h> /* For the statistics structure. */
0051 #include <linux/if_arp.h>   /* For ARPHRD_ETHER */
0052 #include <linux/ip.h>
0053 #include <linux/tcp.h>
0054 #include <linux/percpu.h>
0055 #include <linux/net_tstamp.h>
0056 #include <net/net_namespace.h>
0057 #include <linux/u64_stats_sync.h>
0058 
0059 /* blackhole_netdev - a device used for dsts that are marked expired!
0060  * This is global device (instead of per-net-ns) since it's not needed
0061  * to be per-ns and gets initialized at boot time.
0062  */
0063 struct net_device *blackhole_netdev;
0064 EXPORT_SYMBOL(blackhole_netdev);
0065 
0066 /* The higher levels take care of making this non-reentrant (it's
0067  * called with bh's disabled).
0068  */
0069 static netdev_tx_t loopback_xmit(struct sk_buff *skb,
0070                  struct net_device *dev)
0071 {
0072     int len;
0073 
0074     skb_tx_timestamp(skb);
0075 
0076     /* do not fool net_timestamp_check() with various clock bases */
0077     skb_clear_tstamp(skb);
0078 
0079     skb_orphan(skb);
0080 
0081     /* Before queueing this packet to __netif_rx(),
0082      * make sure dst is refcounted.
0083      */
0084     skb_dst_force(skb);
0085 
0086     skb->protocol = eth_type_trans(skb, dev);
0087 
0088     len = skb->len;
0089     if (likely(__netif_rx(skb) == NET_RX_SUCCESS))
0090         dev_lstats_add(dev, len);
0091 
0092     return NETDEV_TX_OK;
0093 }
0094 
0095 void dev_lstats_read(struct net_device *dev, u64 *packets, u64 *bytes)
0096 {
0097     int i;
0098 
0099     *packets = 0;
0100     *bytes = 0;
0101 
0102     for_each_possible_cpu(i) {
0103         const struct pcpu_lstats *lb_stats;
0104         u64 tbytes, tpackets;
0105         unsigned int start;
0106 
0107         lb_stats = per_cpu_ptr(dev->lstats, i);
0108         do {
0109             start = u64_stats_fetch_begin_irq(&lb_stats->syncp);
0110             tpackets = u64_stats_read(&lb_stats->packets);
0111             tbytes = u64_stats_read(&lb_stats->bytes);
0112         } while (u64_stats_fetch_retry_irq(&lb_stats->syncp, start));
0113         *bytes   += tbytes;
0114         *packets += tpackets;
0115     }
0116 }
0117 EXPORT_SYMBOL(dev_lstats_read);
0118 
0119 static void loopback_get_stats64(struct net_device *dev,
0120                  struct rtnl_link_stats64 *stats)
0121 {
0122     u64 packets, bytes;
0123 
0124     dev_lstats_read(dev, &packets, &bytes);
0125 
0126     stats->rx_packets = packets;
0127     stats->tx_packets = packets;
0128     stats->rx_bytes   = bytes;
0129     stats->tx_bytes   = bytes;
0130 }
0131 
0132 static u32 always_on(struct net_device *dev)
0133 {
0134     return 1;
0135 }
0136 
0137 static const struct ethtool_ops loopback_ethtool_ops = {
0138     .get_link       = always_on,
0139     .get_ts_info        = ethtool_op_get_ts_info,
0140 };
0141 
0142 static int loopback_dev_init(struct net_device *dev)
0143 {
0144     dev->lstats = netdev_alloc_pcpu_stats(struct pcpu_lstats);
0145     if (!dev->lstats)
0146         return -ENOMEM;
0147     return 0;
0148 }
0149 
0150 static void loopback_dev_free(struct net_device *dev)
0151 {
0152     dev_net(dev)->loopback_dev = NULL;
0153     free_percpu(dev->lstats);
0154 }
0155 
0156 static const struct net_device_ops loopback_ops = {
0157     .ndo_init        = loopback_dev_init,
0158     .ndo_start_xmit  = loopback_xmit,
0159     .ndo_get_stats64 = loopback_get_stats64,
0160     .ndo_set_mac_address = eth_mac_addr,
0161 };
0162 
0163 static void gen_lo_setup(struct net_device *dev,
0164              unsigned int mtu,
0165              const struct ethtool_ops *eth_ops,
0166              const struct header_ops *hdr_ops,
0167              const struct net_device_ops *dev_ops,
0168              void (*dev_destructor)(struct net_device *dev))
0169 {
0170     dev->mtu        = mtu;
0171     dev->hard_header_len    = ETH_HLEN; /* 14   */
0172     dev->min_header_len = ETH_HLEN; /* 14   */
0173     dev->addr_len       = ETH_ALEN; /* 6    */
0174     dev->type       = ARPHRD_LOOPBACK;  /* 0x0001*/
0175     dev->flags      = IFF_LOOPBACK;
0176     dev->priv_flags     |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE;
0177     netif_keep_dst(dev);
0178     dev->hw_features    = NETIF_F_GSO_SOFTWARE;
0179     dev->features       = NETIF_F_SG | NETIF_F_FRAGLIST
0180         | NETIF_F_GSO_SOFTWARE
0181         | NETIF_F_HW_CSUM
0182         | NETIF_F_RXCSUM
0183         | NETIF_F_SCTP_CRC
0184         | NETIF_F_HIGHDMA
0185         | NETIF_F_LLTX
0186         | NETIF_F_NETNS_LOCAL
0187         | NETIF_F_VLAN_CHALLENGED
0188         | NETIF_F_LOOPBACK;
0189     dev->ethtool_ops    = eth_ops;
0190     dev->header_ops     = hdr_ops;
0191     dev->netdev_ops     = dev_ops;
0192     dev->needs_free_netdev  = true;
0193     dev->priv_destructor    = dev_destructor;
0194 
0195     netif_set_tso_max_size(dev, GSO_MAX_SIZE);
0196 }
0197 
0198 /* The loopback device is special. There is only one instance
0199  * per network namespace.
0200  */
0201 static void loopback_setup(struct net_device *dev)
0202 {
0203     gen_lo_setup(dev, (64 * 1024), &loopback_ethtool_ops, &eth_header_ops,
0204              &loopback_ops, loopback_dev_free);
0205 }
0206 
0207 /* Setup and register the loopback device. */
0208 static __net_init int loopback_net_init(struct net *net)
0209 {
0210     struct net_device *dev;
0211     int err;
0212 
0213     err = -ENOMEM;
0214     dev = alloc_netdev(0, "lo", NET_NAME_UNKNOWN, loopback_setup);
0215     if (!dev)
0216         goto out;
0217 
0218     dev_net_set(dev, net);
0219     err = register_netdev(dev);
0220     if (err)
0221         goto out_free_netdev;
0222 
0223     BUG_ON(dev->ifindex != LOOPBACK_IFINDEX);
0224     net->loopback_dev = dev;
0225     return 0;
0226 
0227 out_free_netdev:
0228     free_netdev(dev);
0229 out:
0230     if (net_eq(net, &init_net))
0231         panic("loopback: Failed to register netdevice: %d\n", err);
0232     return err;
0233 }
0234 
0235 /* Registered in net/core/dev.c */
0236 struct pernet_operations __net_initdata loopback_net_ops = {
0237     .init = loopback_net_init,
0238 };
0239 
0240 /* blackhole netdevice */
0241 static netdev_tx_t blackhole_netdev_xmit(struct sk_buff *skb,
0242                      struct net_device *dev)
0243 {
0244     kfree_skb(skb);
0245     net_warn_ratelimited("%s(): Dropping skb.\n", __func__);
0246     return NETDEV_TX_OK;
0247 }
0248 
0249 static const struct net_device_ops blackhole_netdev_ops = {
0250     .ndo_start_xmit = blackhole_netdev_xmit,
0251 };
0252 
0253 /* This is a dst-dummy device used specifically for invalidated
0254  * DSTs and unlike loopback, this is not per-ns.
0255  */
0256 static void blackhole_netdev_setup(struct net_device *dev)
0257 {
0258     gen_lo_setup(dev, ETH_MIN_MTU, NULL, NULL, &blackhole_netdev_ops, NULL);
0259 }
0260 
0261 /* Setup and register the blackhole_netdev. */
0262 static int __init blackhole_netdev_init(void)
0263 {
0264     blackhole_netdev = alloc_netdev(0, "blackhole_dev", NET_NAME_UNKNOWN,
0265                     blackhole_netdev_setup);
0266     if (!blackhole_netdev)
0267         return -ENOMEM;
0268 
0269     rtnl_lock();
0270     dev_init_scheduler(blackhole_netdev);
0271     dev_activate(blackhole_netdev);
0272     rtnl_unlock();
0273 
0274     blackhole_netdev->flags |= IFF_UP | IFF_RUNNING;
0275     dev_net_set(blackhole_netdev, &init_net);
0276 
0277     return 0;
0278 }
0279 
0280 device_initcall(blackhole_netdev_init);