drivers/net/bareudp.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/bareudp.c
Extension
.c
Size
21194 bytes
Lines
830
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 bareudp_netdev_ops = {
	.ndo_init               = bareudp_init,
	.ndo_uninit             = bareudp_uninit,
	.ndo_open               = bareudp_open,
	.ndo_stop               = bareudp_stop,
	.ndo_start_xmit         = bareudp_xmit,
	.ndo_fill_metadata_dst  = bareudp_fill_metadata_dst,
};

static const struct nla_policy bareudp_policy[IFLA_BAREUDP_MAX + 1] = {
	[IFLA_BAREUDP_PORT]                = { .type = NLA_U16 },
	[IFLA_BAREUDP_ETHERTYPE]	   = { .type = NLA_U16 },
	[IFLA_BAREUDP_SRCPORT_MIN]         = { .type = NLA_U16 },
	[IFLA_BAREUDP_MULTIPROTO_MODE]     = { .type = NLA_FLAG },
};

/* Info for udev, that this is a virtual tunnel endpoint */
static const struct device_type bareudp_type = {
	.name = "bareudp",
};

/* Initialize the device structure. */
static void bareudp_setup(struct net_device *dev)
{
	dev->netdev_ops = &bareudp_netdev_ops;
	dev->needs_free_netdev = true;
	SET_NETDEV_DEVTYPE(dev, &bareudp_type);
	dev->features    |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_FRAGLIST;
	dev->features    |= NETIF_F_RXCSUM;
	dev->features    |= NETIF_F_GSO_SOFTWARE;
	dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_FRAGLIST;
	dev->hw_features |= NETIF_F_RXCSUM;
	dev->hw_features |= NETIF_F_GSO_SOFTWARE;
	dev->hard_header_len = 0;
	dev->addr_len = 0;
	dev->mtu = ETH_DATA_LEN;
	dev->min_mtu = IPV4_MIN_MTU;
	dev->max_mtu = IP_MAX_MTU - BAREUDP_BASE_HLEN;
	dev->type = ARPHRD_NONE;
	netif_keep_dst(dev);
	dev->priv_flags |= IFF_NO_QUEUE;
	dev->lltx = true;
	dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
	dev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS;
}

static int bareudp_validate(struct nlattr *tb[], struct nlattr *data[],
			    struct netlink_ext_ack *extack)
{
	if (!data) {
		NL_SET_ERR_MSG(extack,
			       "Not enough attributes provided to perform the operation");
		return -EINVAL;
	}
	return 0;
}

static int bareudp2info(struct nlattr *data[], struct bareudp_conf *conf,
			struct netlink_ext_ack *extack)
{
	memset(conf, 0, sizeof(*conf));

	if (!data[IFLA_BAREUDP_PORT]) {
		NL_SET_ERR_MSG(extack, "port not specified");
		return -EINVAL;
	}
	if (!data[IFLA_BAREUDP_ETHERTYPE]) {
		NL_SET_ERR_MSG(extack, "ethertype not specified");
		return -EINVAL;
	}

	conf->port = nla_get_u16(data[IFLA_BAREUDP_PORT]);
	conf->ethertype = nla_get_u16(data[IFLA_BAREUDP_ETHERTYPE]);

	if (data[IFLA_BAREUDP_SRCPORT_MIN])
		conf->sport_min =  nla_get_u16(data[IFLA_BAREUDP_SRCPORT_MIN]);

	if (data[IFLA_BAREUDP_MULTIPROTO_MODE])
		conf->multi_proto_mode = true;

	return 0;
}

static struct bareudp_dev *bareudp_find_dev(struct bareudp_net *bn,
					    const struct bareudp_conf *conf)
{
	struct bareudp_dev *bareudp, *t = NULL;

	list_for_each_entry(bareudp, &bn->bareudp_list, next) {
		if (conf->port == bareudp->port)

Annotation

Implementation Notes