drivers/net/wireguard/selftest/allowedips.c

Source file repositories/reference/linux-study-clean/drivers/net/wireguard/selftest/allowedips.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireguard/selftest/allowedips.c
Extension
.c
Size
22290 bytes
Lines
728
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source 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

struct horrible_allowedips {
	struct hlist_head head;
};

struct horrible_allowedips_node {
	struct hlist_node table;
	union nf_inet_addr ip;
	union nf_inet_addr mask;
	u8 ip_version;
	void *value;
};

static __init void horrible_allowedips_init(struct horrible_allowedips *table)
{
	INIT_HLIST_HEAD(&table->head);
}

static __init void horrible_allowedips_free(struct horrible_allowedips *table)
{
	struct horrible_allowedips_node *node;
	struct hlist_node *h;

	hlist_for_each_entry_safe(node, h, &table->head, table) {
		hlist_del(&node->table);
		kfree(node);
	}
}

static __init inline union nf_inet_addr horrible_cidr_to_mask(u8 cidr)
{
	union nf_inet_addr mask;

	memset(&mask, 0, sizeof(mask));
	memset(&mask.all, 0xff, cidr / 8);
	if (cidr % 32)
		mask.all[cidr / 32] = (__force u32)htonl(
			(0xFFFFFFFFUL << (32 - (cidr % 32))) & 0xFFFFFFFFUL);
	return mask;
}

static __init inline u8 horrible_mask_to_cidr(union nf_inet_addr subnet)
{
	return hweight32(subnet.all[0]) + hweight32(subnet.all[1]) +
	       hweight32(subnet.all[2]) + hweight32(subnet.all[3]);
}

static __init inline void
horrible_mask_self(struct horrible_allowedips_node *node)
{
	if (node->ip_version == 4) {
		node->ip.ip &= node->mask.ip;
	} else if (node->ip_version == 6) {
		node->ip.ip6[0] &= node->mask.ip6[0];
		node->ip.ip6[1] &= node->mask.ip6[1];
		node->ip.ip6[2] &= node->mask.ip6[2];
		node->ip.ip6[3] &= node->mask.ip6[3];
	}
}

static __init inline bool
horrible_match_v4(const struct horrible_allowedips_node *node, struct in_addr *ip)
{
	return (ip->s_addr & node->mask.ip) == node->ip.ip;
}

static __init inline bool
horrible_match_v6(const struct horrible_allowedips_node *node, struct in6_addr *ip)
{
	return (ip->in6_u.u6_addr32[0] & node->mask.ip6[0]) == node->ip.ip6[0] &&
	       (ip->in6_u.u6_addr32[1] & node->mask.ip6[1]) == node->ip.ip6[1] &&
	       (ip->in6_u.u6_addr32[2] & node->mask.ip6[2]) == node->ip.ip6[2] &&
	       (ip->in6_u.u6_addr32[3] & node->mask.ip6[3]) == node->ip.ip6[3];
}

static __init void
horrible_insert_ordered(struct horrible_allowedips *table, struct horrible_allowedips_node *node)
{
	struct horrible_allowedips_node *other = NULL, *where = NULL;
	u8 my_cidr = horrible_mask_to_cidr(node->mask);

	hlist_for_each_entry(other, &table->head, table) {
		if (other->ip_version == node->ip_version &&
		    !memcmp(&other->mask, &node->mask, sizeof(union nf_inet_addr)) &&
		    !memcmp(&other->ip, &node->ip, sizeof(union nf_inet_addr))) {
			other->value = node->value;
			kfree(node);
			return;
		}
	}
	hlist_for_each_entry(other, &table->head, table) {

Annotation

Implementation Notes