net/8021q/vlan.h

Source file repositories/reference/linux-study-clean/net/8021q/vlan.h

File Facts

System
Linux kernel
Corpus path
net/8021q/vlan.h
Extension
.h
Size
6493 bytes
Lines
208
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

struct vlan_group {
	unsigned int		nr_vlan_devs;
	struct hlist_node	hlist;	/* linked list */
	struct net_device **vlan_devices_arrays[VLAN_PROTO_NUM]
					       [VLAN_GROUP_ARRAY_SPLIT_PARTS];
};

struct vlan_info {
	struct net_device	*real_dev; /* The ethernet(like) device
					    * the vlan is attached to.
					    */
	struct vlan_group	grp;
	struct list_head	vid_list;
	unsigned int		nr_vids;
	bool			auto_vid0;
	struct rcu_head		rcu;
};

static inline int vlan_proto_idx(__be16 proto)
{
	switch (proto) {
	case htons(ETH_P_8021Q):
		return VLAN_PROTO_8021Q;
	case htons(ETH_P_8021AD):
		return VLAN_PROTO_8021AD;
	default:
		WARN(1, "invalid VLAN protocol: 0x%04x\n", ntohs(proto));
		return -EINVAL;
	}
}

static inline struct net_device *__vlan_group_get_device(struct vlan_group *vg,
							 unsigned int pidx,
							 u16 vlan_id)
{
	struct net_device **array;

	array = vg->vlan_devices_arrays[pidx]
				       [vlan_id / VLAN_GROUP_ARRAY_PART_LEN];

	/* paired with smp_wmb() in vlan_group_prealloc_vid() */
	smp_rmb();

	return array ? array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] : NULL;
}

static inline struct net_device *vlan_group_get_device(struct vlan_group *vg,
						       __be16 vlan_proto,
						       u16 vlan_id)
{
	int pidx = vlan_proto_idx(vlan_proto);

	if (pidx < 0)
		return NULL;

	return __vlan_group_get_device(vg, pidx, vlan_id);
}

static inline void vlan_group_set_device(struct vlan_group *vg,
					 __be16 vlan_proto, u16 vlan_id,
					 struct net_device *dev)
{
	int pidx = vlan_proto_idx(vlan_proto);
	struct net_device **array;

	if (!vg || pidx < 0)
		return;
	array = vg->vlan_devices_arrays[pidx]
				       [vlan_id / VLAN_GROUP_ARRAY_PART_LEN];
	array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev;
}

/* Must be invoked with rcu_read_lock or with RTNL. */
static inline struct net_device *vlan_find_dev(struct net_device *real_dev,
					       __be16 vlan_proto, u16 vlan_id)
{
	struct vlan_info *vlan_info = rcu_dereference_rtnl(real_dev->vlan_info);

	if (vlan_info)
		return vlan_group_get_device(&vlan_info->grp,
					     vlan_proto, vlan_id);

	return NULL;
}

static inline netdev_features_t vlan_tnl_features(struct net_device *real_dev)
{
	netdev_features_t ret;

	ret = real_dev->hw_enc_features &

Annotation

Implementation Notes