drivers/net/tap.c
Source file repositories/reference/linux-study-clean/drivers/net/tap.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/tap.c- Extension
.c- Size
- 29561 bytes
- Lines
- 1288
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/etherdevice.hlinux/if_tap.hlinux/if_vlan.hlinux/interrupt.hlinux/nsproxy.hlinux/compat.hlinux/if_tun.hlinux/module.hlinux/skbuff.hlinux/cache.hlinux/sched/signal.hlinux/types.hlinux/slab.hlinux/wait.hlinux/cdev.hlinux/idr.hlinux/fs.hlinux/uio.hnet/gso.hnet/net_namespace.hnet/rtnetlink.hnet/sock.hnet/xdp.hlinux/virtio_net.hlinux/skb_array.htun_vnet.h
Detected Declarations
struct major_infofunction sock_holdfunction tap_set_queuefunction tap_disable_queuefunction tap_put_queuefunction tap_del_queuesfunction tap_handle_framefunction skb_list_walk_safefunction list_for_each_entry_rcufunction tap_get_minorfunction tap_free_minorfunction tap_sock_write_spacefunction tap_sock_destructfunction tap_openfunction tap_releasefunction tap_pollfunction tap_get_userfunction tap_write_iterfunction tap_put_userfunction tap_do_readfunction tap_read_iterfunction tap_put_tap_devfunction tap_ioctl_set_queuefunction set_offloadfunction tap_ioctlfunction tap_get_user_xdpfunction tap_sendmsgfunction tap_recvmsgfunction tap_peek_lenfunction tap_queue_resizefunction tap_list_addfunction tap_create_cdevfunction tap_destroy_cdevexport tap_del_queuesexport tap_handle_frameexport tap_get_minorexport tap_free_minorexport tap_get_socketexport tap_get_ptr_ringexport tap_queue_resizeexport tap_create_cdevexport tap_destroy_cdev
Annotated Snippet
static const struct proto_ops tap_socket_ops;
#define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO)
#define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG | NETIF_F_FRAGLIST)
static struct tap_dev *tap_dev_get_rcu(const struct net_device *dev)
{
return rcu_dereference(dev->rx_handler_data);
}
/*
* RCU usage:
* The tap_queue and the macvlan_dev are loosely coupled, the
* pointers from one to the other can only be read while rcu_read_lock
* or rtnl is held.
*
* Both the file and the macvlan_dev hold a reference on the tap_queue
* through sock_hold(&q->sk). When the macvlan_dev goes away first,
* q->vlan becomes inaccessible. When the files gets closed,
* tap_get_queue() fails.
*
* There may still be references to the struct sock inside of the
* queue from outbound SKBs, but these never reference back to the
* file or the dev. The data structure is freed through __sk_free
* when both our references and any pending SKBs are gone.
*/
static int tap_enable_queue(struct tap_dev *tap, struct file *file,
struct tap_queue *q)
{
int err = -EINVAL;
ASSERT_RTNL();
if (q->enabled)
goto out;
err = 0;
rcu_assign_pointer(tap->taps[tap->numvtaps], q);
q->queue_index = tap->numvtaps;
q->enabled = true;
tap->numvtaps++;
out:
return err;
}
/* Requires RTNL */
static int tap_set_queue(struct tap_dev *tap, struct file *file,
struct tap_queue *q)
{
if (tap->numqueues == MAX_TAP_QUEUES)
return -EBUSY;
rcu_assign_pointer(q->tap, tap);
rcu_assign_pointer(tap->taps[tap->numvtaps], q);
sock_hold(&q->sk);
q->file = file;
q->queue_index = tap->numvtaps;
q->enabled = true;
file->private_data = q;
list_add_tail(&q->next, &tap->queue_list);
tap->numvtaps++;
tap->numqueues++;
return 0;
}
static int tap_disable_queue(struct tap_queue *q)
{
struct tap_dev *tap;
struct tap_queue *nq;
ASSERT_RTNL();
if (!q->enabled)
return -EINVAL;
tap = rtnl_dereference(q->tap);
if (tap) {
int index = q->queue_index;
BUG_ON(index >= tap->numvtaps);
nq = rtnl_dereference(tap->taps[tap->numvtaps - 1]);
nq->queue_index = index;
rcu_assign_pointer(tap->taps[index], nq);
RCU_INIT_POINTER(tap->taps[tap->numvtaps - 1], NULL);
q->enabled = false;
Annotation
- Immediate include surface: `linux/etherdevice.h`, `linux/if_tap.h`, `linux/if_vlan.h`, `linux/interrupt.h`, `linux/nsproxy.h`, `linux/compat.h`, `linux/if_tun.h`, `linux/module.h`.
- Detected declarations: `struct major_info`, `function sock_hold`, `function tap_set_queue`, `function tap_disable_queue`, `function tap_put_queue`, `function tap_del_queues`, `function tap_handle_frame`, `function skb_list_walk_safe`, `function list_for_each_entry_rcu`, `function tap_get_minor`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.