10243 lines · 253.9 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-or-later/* *      NET3    Protocol independent device support routines. * *	Derived from the non IP parts of dev.c 1.0.19 *              Authors:	Ross Biro *				Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> *				Mark Evans, <evansmp@uhura.aston.ac.uk> * *	Additional Authors: *		Florian la Roche <rzsfl@rz.uni-sb.de> *		Alan Cox <gw4pts@gw4pts.ampr.org> *		David Hinds <dahinds@users.sourceforge.net> *		Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> *		Adam Sulmicki <adam@cfar.umd.edu> *              Pekka Riikonen <priikone@poesidon.pspt.fi> * *	Changes: *              D.J. Barrow     :       Fixed bug where dev->refcnt gets set *                                      to 2 if register_netdev gets called *                                      before net_dev_init & also removed a *                                      few lines of code in the process. *		Alan Cox	:	device private ioctl copies fields back. *		Alan Cox	:	Transmit queue code does relevant *					stunts to keep the queue safe. *		Alan Cox	:	Fixed double lock. *		Alan Cox	:	Fixed promisc NULL pointer trap *		????????	:	Support the full private ioctl range *		Alan Cox	:	Moved ioctl permission check into *					drivers *		Tim Kordas	:	SIOCADDMULTI/SIOCDELMULTI *		Alan Cox	:	100 backlog just doesn't cut it when *					you start doing multicast video 8) *		Alan Cox	:	Rewrote net_bh and list manager. *              Alan Cox        :       Fix ETH_P_ALL echoback lengths. *		Alan Cox	:	Took out transmit every packet pass *					Saved a few bytes in the ioctl handler *		Alan Cox	:	Network driver sets packet type before *					calling netif_rx. Saves a function *					call a packet. *		Alan Cox	:	Hashed net_bh() *		Richard Kooijman:	Timestamp fixes. *		Alan Cox	:	Wrong field in SIOCGIFDSTADDR *		Alan Cox	:	Device lock protection. *              Alan Cox        :       Fixed nasty side effect of device close *					changes. *		Rudi Cilibrasi	:	Pass the right thing to *					set_mac_address() *		Dave Miller	:	32bit quantity for the device lock to *					make it work out on a Sparc. *		Bjorn Ekwall	:	Added KERNELD hack. *		Alan Cox	:	Cleaned up the backlog initialise. *		Craig Metz	:	SIOCGIFCONF fix if space for under *					1 device. *	    Thomas Bogendoerfer :	Return ENODEV for dev_open, if there *					is no device open function. *		Andi Kleen	:	Fix error reporting for SIOCGIFCONF *	    Michael Chastain	:	Fix signed/unsigned for SIOCGIFCONF *		Cyrus Durgin	:	Cleaned for KMOD *		Adam Sulmicki   :	Bug Fix : Network Device Unload *					A network device unload needs to purge *					the backlog queue. *	Paul Rusty Russell	:	SIOCSIFNAME *              Pekka Riikonen  :	Netdev boot-time settings code *              Andrew Morton   :       Make unregister_netdevice wait *                                      indefinitely on dev->refcnt *              J Hadi Salim    :       - Backlog queue sampling *				        - netif_rx() feedback */ #include <linux/uaccess.h>#include <linux/bitops.h>#include <linux/capability.h>#include <linux/cpu.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/hash.h>#include <linux/slab.h>#include <linux/sched.h>#include <linux/sched/mm.h>#include <linux/mutex.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/socket.h>#include <linux/sockios.h>#include <linux/errno.h>#include <linux/interrupt.h>#include <linux/if_ether.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/ethtool.h>#include <linux/skbuff.h>#include <linux/bpf.h>#include <linux/bpf_trace.h>#include <net/net_namespace.h>#include <net/sock.h>#include <net/busy_poll.h>#include <linux/rtnetlink.h>#include <linux/stat.h>#include <net/dst.h>#include <net/dst_metadata.h>#include <net/pkt_sched.h>#include <net/pkt_cls.h>#include <net/checksum.h>#include <net/xfrm.h>#include <linux/highmem.h>#include <linux/init.h>#include <linux/module.h>#include <linux/netpoll.h>#include <linux/rcupdate.h>#include <linux/delay.h>#include <net/iw_handler.h>#include <asm/current.h>#include <linux/audit.h>#include <linux/dmaengine.h>#include <linux/err.h>#include <linux/ctype.h>#include <linux/if_arp.h>#include <linux/if_vlan.h>#include <linux/ip.h>#include <net/ip.h>#include <net/mpls.h>#include <linux/ipv6.h>#include <linux/in.h>#include <linux/jhash.h>#include <linux/random.h>#include <trace/events/napi.h>#include <trace/events/net.h>#include <trace/events/skb.h>#include <linux/inetdevice.h>#include <linux/cpu_rmap.h>#include <linux/static_key.h>#include <linux/hashtable.h>#include <linux/vmalloc.h>#include <linux/if_macvlan.h>#include <linux/errqueue.h>#include <linux/hrtimer.h>#include <linux/netfilter_ingress.h>#include <linux/crash_dump.h>#include <linux/sctp.h>#include <net/udp_tunnel.h>#include <linux/net_namespace.h>#include <linux/indirect_call_wrapper.h>#include <net/devlink.h> #include "net-sysfs.h" #define MAX_GRO_SKBS 8#define MAX_NEST_DEV 8 /* This should be increased if a protocol with a bigger head is added. */#define GRO_MAX_HEAD (MAX_HEADER + 128) static DEFINE_SPINLOCK(ptype_lock);static DEFINE_SPINLOCK(offload_lock);struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly;struct list_head ptype_all __read_mostly;	/* Taps */static struct list_head offload_base __read_mostly; static int netif_rx_internal(struct sk_buff *skb);static int call_netdevice_notifiers_info(unsigned long val,					 struct netdev_notifier_info *info);static int call_netdevice_notifiers_extack(unsigned long val,					   struct net_device *dev,					   struct netlink_ext_ack *extack);static struct napi_struct *napi_by_id(unsigned int napi_id); /* * The @dev_base_head list is protected by @dev_base_lock and the rtnl * semaphore. * * Pure readers hold dev_base_lock for reading, or rcu_read_lock() * * Writers must hold the rtnl semaphore while they loop through the * dev_base_head list, and hold dev_base_lock for writing when they do the * actual updates.  This allows pure readers to access the list even * while a writer is preparing to update it. * * To put it another way, dev_base_lock is held for writing only to * protect against pure readers; the rtnl semaphore provides the * protection against other writers. * * See, for example usages, register_netdevice() and * unregister_netdevice(), which must be called with the rtnl * semaphore held. */DEFINE_RWLOCK(dev_base_lock);EXPORT_SYMBOL(dev_base_lock); static DEFINE_MUTEX(ifalias_mutex); /* protects napi_hash addition/deletion and napi_gen_id */static DEFINE_SPINLOCK(napi_hash_lock); static unsigned int napi_gen_id = NR_CPUS;static DEFINE_READ_MOSTLY_HASHTABLE(napi_hash, 8); static seqcount_t devnet_rename_seq; static inline void dev_base_seq_inc(struct net *net){	while (++net->dev_base_seq == 0)		;} static inline struct hlist_head *dev_name_hash(struct net *net, const char *name){	unsigned int hash = full_name_hash(net, name, strnlen(name, IFNAMSIZ)); 	return &net->dev_name_head[hash_32(hash, NETDEV_HASHBITS)];} static inline struct hlist_head *dev_index_hash(struct net *net, int ifindex){	return &net->dev_index_head[ifindex & (NETDEV_HASHENTRIES - 1)];} static inline void rps_lock(struct softnet_data *sd){#ifdef CONFIG_RPS	spin_lock(&sd->input_pkt_queue.lock);#endif} static inline void rps_unlock(struct softnet_data *sd){#ifdef CONFIG_RPS	spin_unlock(&sd->input_pkt_queue.lock);#endif} /* Device list insertion */static void list_netdevice(struct net_device *dev){	struct net *net = dev_net(dev); 	ASSERT_RTNL(); 	write_lock_bh(&dev_base_lock);	list_add_tail_rcu(&dev->dev_list, &net->dev_base_head);	hlist_add_head_rcu(&dev->name_hlist, dev_name_hash(net, dev->name));	hlist_add_head_rcu(&dev->index_hlist,			   dev_index_hash(net, dev->ifindex));	write_unlock_bh(&dev_base_lock); 	dev_base_seq_inc(net);} /* Device list removal * caller must respect a RCU grace period before freeing/reusing dev */static void unlist_netdevice(struct net_device *dev){	ASSERT_RTNL(); 	/* Unlink dev from the device chain */	write_lock_bh(&dev_base_lock);	list_del_rcu(&dev->dev_list);	hlist_del_rcu(&dev->name_hlist);	hlist_del_rcu(&dev->index_hlist);	write_unlock_bh(&dev_base_lock); 	dev_base_seq_inc(dev_net(dev));} /* *	Our notifier list */ static RAW_NOTIFIER_HEAD(netdev_chain); /* *	Device drivers call our routines to queue packets here. We empty the *	queue in the local softnet handler. */ DEFINE_PER_CPU_ALIGNED(struct softnet_data, softnet_data);EXPORT_PER_CPU_SYMBOL(softnet_data); /******************************************************************************* * *		Protocol management and registration routines * *******************************************************************************/  /* *	Add a protocol ID to the list. Now that the input handler is *	smarter we can dispense with all the messy stuff that used to be *	here. * *	BEWARE!!! Protocol handlers, mangling input packets, *	MUST BE last in hash buckets and checking protocol handlers *	MUST start from promiscuous ptype_all chain in net_bh. *	It is true now, do not change it. *	Explanation follows: if protocol handler, mangling packet, will *	be the first on list, it is not able to sense, that packet *	is cloned and should be copied-on-write, so that it will *	change it and subsequent readers will get broken packet. *							--ANK (980803) */ static inline struct list_head *ptype_head(const struct packet_type *pt){	if (pt->type == htons(ETH_P_ALL))		return pt->dev ? &pt->dev->ptype_all : &ptype_all;	else		return pt->dev ? &pt->dev->ptype_specific :				 &ptype_base[ntohs(pt->type) & PTYPE_HASH_MASK];} /** *	dev_add_pack - add packet handler *	@pt: packet type declaration * *	Add a protocol handler to the networking stack. The passed &packet_type *	is linked into kernel lists and may not be freed until it has been *	removed from the kernel lists. * *	This call does not sleep therefore it can not *	guarantee all CPU's that are in middle of receiving packets *	will see the new packet type (until the next received packet). */ void dev_add_pack(struct packet_type *pt){	struct list_head *head = ptype_head(pt); 	spin_lock(&ptype_lock);	list_add_rcu(&pt->list, head);	spin_unlock(&ptype_lock);}EXPORT_SYMBOL(dev_add_pack); /** *	__dev_remove_pack	 - remove packet handler *	@pt: packet type declaration * *	Remove a protocol handler that was previously added to the kernel *	protocol handlers by dev_add_pack(). The passed &packet_type is removed *	from the kernel lists and can be freed or reused once this function *	returns. * *      The packet type might still be in use by receivers *	and must not be freed until after all the CPU's have gone *	through a quiescent state. */void __dev_remove_pack(struct packet_type *pt){	struct list_head *head = ptype_head(pt);	struct packet_type *pt1; 	spin_lock(&ptype_lock); 	list_for_each_entry(pt1, head, list) {		if (pt == pt1) {			list_del_rcu(&pt->list);			goto out;		}	} 	pr_warn("dev_remove_pack: %p not found\n", pt);out:	spin_unlock(&ptype_lock);}EXPORT_SYMBOL(__dev_remove_pack); /** *	dev_remove_pack	 - remove packet handler *	@pt: packet type declaration * *	Remove a protocol handler that was previously added to the kernel *	protocol handlers by dev_add_pack(). The passed &packet_type is removed *	from the kernel lists and can be freed or reused once this function *	returns. * *	This call sleeps to guarantee that no CPU is looking at the packet *	type after return. */void dev_remove_pack(struct packet_type *pt){	__dev_remove_pack(pt); 	synchronize_net();}EXPORT_SYMBOL(dev_remove_pack);  /** *	dev_add_offload - register offload handlers *	@po: protocol offload declaration * *	Add protocol offload handlers to the networking stack. The passed *	&proto_offload is linked into kernel lists and may not be freed until *	it has been removed from the kernel lists. * *	This call does not sleep therefore it can not *	guarantee all CPU's that are in middle of receiving packets *	will see the new offload handlers (until the next received packet). */void dev_add_offload(struct packet_offload *po){	struct packet_offload *elem; 	spin_lock(&offload_lock);	list_for_each_entry(elem, &offload_base, list) {		if (po->priority < elem->priority)			break;	}	list_add_rcu(&po->list, elem->list.prev);	spin_unlock(&offload_lock);}EXPORT_SYMBOL(dev_add_offload); /** *	__dev_remove_offload	 - remove offload handler *	@po: packet offload declaration * *	Remove a protocol offload handler that was previously added to the *	kernel offload handlers by dev_add_offload(). The passed &offload_type *	is removed from the kernel lists and can be freed or reused once this *	function returns. * *      The packet type might still be in use by receivers *	and must not be freed until after all the CPU's have gone *	through a quiescent state. */static void __dev_remove_offload(struct packet_offload *po){	struct list_head *head = &offload_base;	struct packet_offload *po1; 	spin_lock(&offload_lock); 	list_for_each_entry(po1, head, list) {		if (po == po1) {			list_del_rcu(&po->list);			goto out;		}	} 	pr_warn("dev_remove_offload: %p not found\n", po);out:	spin_unlock(&offload_lock);} /** *	dev_remove_offload	 - remove packet offload handler *	@po: packet offload declaration * *	Remove a packet offload handler that was previously added to the kernel *	offload handlers by dev_add_offload(). The passed &offload_type is *	removed from the kernel lists and can be freed or reused once this *	function returns. * *	This call sleeps to guarantee that no CPU is looking at the packet *	type after return. */void dev_remove_offload(struct packet_offload *po){	__dev_remove_offload(po); 	synchronize_net();}EXPORT_SYMBOL(dev_remove_offload); /****************************************************************************** * *		      Device Boot-time Settings Routines * ******************************************************************************/ /* Boot time configuration table */static struct netdev_boot_setup dev_boot_setup[NETDEV_BOOT_SETUP_MAX]; /** *	netdev_boot_setup_add	- add new setup entry *	@name: name of the device *	@map: configured settings for the device * *	Adds new setup entry to the dev_boot_setup list.  The function *	returns 0 on error and 1 on success.  This is a generic routine to *	all netdevices. */static int netdev_boot_setup_add(char *name, struct ifmap *map){	struct netdev_boot_setup *s;	int i; 	s = dev_boot_setup;	for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {		if (s[i].name[0] == '\0' || s[i].name[0] == ' ') {			memset(s[i].name, 0, sizeof(s[i].name));			strlcpy(s[i].name, name, IFNAMSIZ);			memcpy(&s[i].map, map, sizeof(s[i].map));			break;		}	} 	return i >= NETDEV_BOOT_SETUP_MAX ? 0 : 1;

Lines 1–500 of 10243.