static struct vlan_group *vlan_group_alloc(int ifindex) { struct vlan_group *grp; unsigned int size; unsigned int i; grp = kzalloc(sizeof(struct vlan_group), GFP_KERNEL); if (!grp) return NULL; size = sizeof(struct net_device *) * VLAN_GROUP_ARRAY_PART_LEN; for (i = 0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++) { grp->vlan_devices_arrays[i] = kzalloc(size, GFP_KERNEL); if (!grp->vlan_devices_arrays[i]) goto err; } grp->real_dev_ifindex = ifindex; hlist_add_head_rcu(&grp->hlist, &vlan_group_hash[vlan_grp_hashfn(ifindex)]); return grp; err: vlan_group_free(grp); return NULL; }
/* Must hold vlan_group_lock. */ static void __grp_hash(struct vlan_group *grp) { struct vlan_group **head; head = &vlan_group_hash[vlan_grp_hashfn(grp->real_dev_ifindex)]; grp->next = *head; *head = grp; }
/* Must hold vlan_group_lock. */ static void __grp_unhash(struct vlan_group *grp) { struct vlan_group *next, **pprev; pprev = &vlan_group_hash[vlan_grp_hashfn(grp->real_dev_ifindex)]; next = *pprev; while (next != grp) { pprev = &next->next; next = *pprev; } *pprev = grp->next; }
/* Must be invoked with vlan_group_lock held. */ static struct vlan_group *__vlan_find_group(int real_dev_ifindex) { struct vlan_group *grp; for (grp = vlan_group_hash[vlan_grp_hashfn(real_dev_ifindex)]; grp != NULL; grp = grp->next) { if (grp->real_dev_ifindex == real_dev_ifindex) break; } return grp; }