drivers/net/macvlan.c

Source file repositories/reference/linux-study-clean/drivers/net/macvlan.c

File Facts

System
Linux kernel
Corpus path
drivers/net/macvlan.c
Extension
.c
Size
50023 bytes
Lines
1904
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.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct net_device_ops macvlan_netdev_ops = {
	.ndo_init		= macvlan_init,
	.ndo_uninit		= macvlan_uninit,
	.ndo_open		= macvlan_open,
	.ndo_stop		= macvlan_stop,
	.ndo_start_xmit		= macvlan_start_xmit,
	.ndo_change_mtu		= macvlan_change_mtu,
	.ndo_fix_features	= macvlan_fix_features,
	.ndo_change_rx_flags	= macvlan_change_rx_flags,
	.ndo_set_mac_address	= macvlan_set_mac_address,
	.ndo_set_rx_mode	= macvlan_set_mac_lists,
	.ndo_get_stats64	= macvlan_dev_get_stats64,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_vlan_rx_add_vid	= macvlan_vlan_rx_add_vid,
	.ndo_vlan_rx_kill_vid	= macvlan_vlan_rx_kill_vid,
	.ndo_fdb_add		= macvlan_fdb_add,
	.ndo_fdb_del		= macvlan_fdb_del,
	.ndo_fdb_dump		= ndo_dflt_fdb_dump,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= macvlan_dev_poll_controller,
	.ndo_netpoll_setup	= macvlan_dev_netpoll_setup,
	.ndo_netpoll_cleanup	= macvlan_dev_netpoll_cleanup,
#endif
	.ndo_get_iflink		= macvlan_dev_get_iflink,
	.ndo_features_check	= passthru_features_check,
	.ndo_hwtstamp_get	= macvlan_hwtstamp_get,
	.ndo_hwtstamp_set	= macvlan_hwtstamp_set,
};

static void macvlan_dev_free(struct net_device *dev)
{
	struct macvlan_dev *vlan = netdev_priv(dev);

	/* Get rid of the macvlan's reference to lowerdev */
	netdev_put(vlan->lowerdev, &vlan->dev_tracker);
}

void macvlan_common_setup(struct net_device *dev)
{
	ether_setup(dev);

	/* ether_setup() has set dev->min_mtu to ETH_MIN_MTU. */
	dev->max_mtu		= ETH_MAX_MTU;
	dev->priv_flags	       &= ~IFF_TX_SKB_SHARING;
	netif_keep_dst(dev);
	dev->priv_flags	       |= IFF_UNICAST_FLT;
	dev->change_proto_down	= true;
	dev->netdev_ops		= &macvlan_netdev_ops;
	dev->needs_free_netdev	= true;
	dev->priv_destructor	= macvlan_dev_free;
	dev->header_ops		= &macvlan_hard_header_ops;
	dev->ethtool_ops	= &macvlan_ethtool_ops;
}
EXPORT_SYMBOL_GPL(macvlan_common_setup);

static void macvlan_setup(struct net_device *dev)
{
	macvlan_common_setup(dev);
	dev->priv_flags |= IFF_NO_QUEUE;
}

static int macvlan_port_create(struct net_device *dev)
{
	struct macvlan_port *port;
	unsigned int i;
	int err;

	if (dev->type != ARPHRD_ETHER || dev->flags & IFF_LOOPBACK)
		return -EINVAL;

	if (netdev_is_rx_handler_busy(dev))
		return -EBUSY;

	port = kzalloc_obj(*port);
	if (port == NULL)
		return -ENOMEM;

	port->dev = dev;
	ether_addr_copy(port->perm_addr, dev->dev_addr);
	INIT_LIST_HEAD(&port->vlans);
	for (i = 0; i < MACVLAN_HASH_SIZE; i++)
		INIT_HLIST_HEAD(&port->vlan_hash[i]);
	for (i = 0; i < MACVLAN_HASH_SIZE; i++)
		INIT_HLIST_HEAD(&port->vlan_source_hash[i]);

	port->bc_queue_len_used = 0;
	port->bc_cutoff = 1;
	skb_queue_head_init(&port->bc_queue);
	INIT_WORK(&port->bc_work, macvlan_process_broadcast);

Annotation

Implementation Notes