^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * INET An implementation of the TCP/IP protocol suite for the LINUX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * operating system. INET is implemented using the BSD Socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * interface as the means of communication with the user level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Pseudo-driver for the loopback interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Version: @(#)loopback.c 1.0.4b 08/16/93
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Authors: Ross Biro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Donald Becker, <becker@scyld.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Alan Cox : Fixed oddments for NET3.014
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Alan Cox : Rejig for NET3.029 snap #3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Alan Cox : Fixed NET3.029 bugs and sped up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Larry McVoy : Tiny tweak to double performance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Alan Cox : Backed out LMV's tweak - the linux mm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * can't take it...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Michael Griffith: Don't bother computing the checksums
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * on packets received on the loopback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Alexey Kuznetsov: Potential hang under some extreme
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * cases removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/socket.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/inet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <net/checksum.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/if_ether.h> /* For the statistics structure. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/if_arp.h> /* For ARPHRD_ETHER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <linux/tcp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <linux/percpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <linux/net_tstamp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <net/net_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <linux/u64_stats_sync.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* blackhole_netdev - a device used for dsts that are marked expired!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * This is global device (instead of per-net-ns) since it's not needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * to be per-ns and gets initialized at boot time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct net_device *blackhole_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) EXPORT_SYMBOL(blackhole_netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* The higher levels take care of making this non-reentrant (it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * called with bh's disabled).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static netdev_tx_t loopback_xmit(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) skb_tx_timestamp(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* do not fool net_timestamp_check() with various clock bases */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) skb->tstamp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) skb_orphan(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* Before queueing this packet to netif_rx(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * make sure dst is refcounted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) skb_dst_force(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) skb->protocol = eth_type_trans(skb, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) len = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (likely(netif_rx(skb) == NET_RX_SUCCESS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) dev_lstats_add(dev, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) void dev_lstats_read(struct net_device *dev, u64 *packets, u64 *bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) *packets = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) *bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) for_each_possible_cpu(i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) const struct pcpu_lstats *lb_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) u64 tbytes, tpackets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) unsigned int start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) lb_stats = per_cpu_ptr(dev->lstats, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) start = u64_stats_fetch_begin_irq(&lb_stats->syncp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) tpackets = u64_stats_read(&lb_stats->packets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) tbytes = u64_stats_read(&lb_stats->bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) } while (u64_stats_fetch_retry_irq(&lb_stats->syncp, start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) *bytes += tbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) *packets += tpackets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) EXPORT_SYMBOL(dev_lstats_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static void loopback_get_stats64(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct rtnl_link_stats64 *stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) u64 packets, bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) dev_lstats_read(dev, &packets, &bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) stats->rx_packets = packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) stats->tx_packets = packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) stats->rx_bytes = bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) stats->tx_bytes = bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static u32 always_on(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static const struct ethtool_ops loopback_ethtool_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .get_link = always_on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .get_ts_info = ethtool_op_get_ts_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static int loopback_dev_init(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) dev->lstats = netdev_alloc_pcpu_stats(struct pcpu_lstats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (!dev->lstats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static void loopback_dev_free(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) dev_net(dev)->loopback_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) free_percpu(dev->lstats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static const struct net_device_ops loopback_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .ndo_init = loopback_dev_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .ndo_start_xmit = loopback_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .ndo_get_stats64 = loopback_get_stats64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .ndo_set_mac_address = eth_mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static void gen_lo_setup(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) unsigned int mtu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) const struct ethtool_ops *eth_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) const struct header_ops *hdr_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) const struct net_device_ops *dev_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) void (*dev_destructor)(struct net_device *dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) dev->mtu = mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) dev->hard_header_len = ETH_HLEN; /* 14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) dev->min_header_len = ETH_HLEN; /* 14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) dev->addr_len = ETH_ALEN; /* 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) dev->type = ARPHRD_LOOPBACK; /* 0x0001*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) dev->flags = IFF_LOOPBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) netif_keep_dst(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) dev->hw_features = NETIF_F_GSO_SOFTWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) | NETIF_F_GSO_SOFTWARE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) | NETIF_F_HW_CSUM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) | NETIF_F_RXCSUM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) | NETIF_F_SCTP_CRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) | NETIF_F_HIGHDMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) | NETIF_F_LLTX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) | NETIF_F_NETNS_LOCAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) | NETIF_F_VLAN_CHALLENGED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) | NETIF_F_LOOPBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) dev->ethtool_ops = eth_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) dev->header_ops = hdr_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) dev->netdev_ops = dev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) dev->needs_free_netdev = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) dev->priv_destructor = dev_destructor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* The loopback device is special. There is only one instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * per network namespace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static void loopback_setup(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) gen_lo_setup(dev, (64 * 1024), &loopback_ethtool_ops, ð_header_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) &loopback_ops, loopback_dev_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* Setup and register the loopback device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static __net_init int loopback_net_init(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) dev = alloc_netdev(0, "lo", NET_NAME_UNKNOWN, loopback_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) dev_net_set(dev, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) err = register_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) goto out_free_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) BUG_ON(dev->ifindex != LOOPBACK_IFINDEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) net->loopback_dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) out_free_netdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (net_eq(net, &init_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) panic("loopback: Failed to register netdevice: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /* Registered in net/core/dev.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct pernet_operations __net_initdata loopback_net_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .init = loopback_net_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* blackhole netdevice */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static netdev_tx_t blackhole_netdev_xmit(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) net_warn_ratelimited("%s(): Dropping skb.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static const struct net_device_ops blackhole_netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .ndo_start_xmit = blackhole_netdev_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* This is a dst-dummy device used specifically for invalidated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * DSTs and unlike loopback, this is not per-ns.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static void blackhole_netdev_setup(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) gen_lo_setup(dev, ETH_MIN_MTU, NULL, NULL, &blackhole_netdev_ops, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /* Setup and register the blackhole_netdev. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static int __init blackhole_netdev_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) blackhole_netdev = alloc_netdev(0, "blackhole_dev", NET_NAME_UNKNOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) blackhole_netdev_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (!blackhole_netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) dev_init_scheduler(blackhole_netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) dev_activate(blackhole_netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) blackhole_netdev->flags |= IFF_UP | IFF_RUNNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) dev_net_set(blackhole_netdev, &init_net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) device_initcall(blackhole_netdev_init);