drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
Extension
.c
Size
38351 bytes
Lines
1366
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

switch (addrs->family) {
		case AF_INET:
			fl4.flowi4_proto = x->sel.proto;
			fl4.daddr = addrs->saddr.a4;
			fl4.saddr = addrs->daddr.a4;
			pkey = &addrs->saddr.a4;
			break;
		case AF_INET6:
			fl6.flowi6_proto = x->sel.proto;
			memcpy(fl6.daddr.s6_addr32, addrs->saddr.a6, 16);
			memcpy(fl6.saddr.s6_addr32, addrs->daddr.a6, 16);
			pkey = &addrs->saddr.a6;
			break;
		default:
			return;
		}
		break;
	case XFRM_DEV_OFFLOAD_OUT:
		src = attrs->smac;
		dst = attrs->dmac;
		switch (addrs->family) {
		case AF_INET:
			fl4.flowi4_proto = x->sel.proto;
			fl4.daddr = addrs->daddr.a4;
			fl4.saddr = addrs->saddr.a4;
			pkey = &addrs->daddr.a4;
			break;
		case AF_INET6:
			fl6.flowi6_proto = x->sel.proto;
			memcpy(fl6.daddr.s6_addr32, addrs->daddr.a6, 16);
			memcpy(fl6.saddr.s6_addr32, addrs->saddr.a6, 16);
			pkey = &addrs->daddr.a6;
			break;
		default:
			return;
		}
		break;
	default:
		return;
	}

	ether_addr_copy(src, addr);

	/* Destination can refer to a routed network, so perform FIB lookup
	 * to resolve nexthop and get its MAC. Neighbour resolution is used as
	 * fallback.
	 */
	switch (addrs->family) {
	case AF_INET:
		rt = ip_route_output_key(dev_net(netdev), &fl4);
		if (IS_ERR(rt))
			goto neigh;

		if (rt->rt_type != RTN_UNICAST) {
			ip_rt_put(rt);
			goto neigh;
		}
		rt_dst_entry = &rt->dst;
		break;
	case AF_INET6:
		if (!IS_ENABLED(CONFIG_IPV6) ||
		    ip6_dst_lookup(dev_net(netdev), NULL, &rt_dst_entry, &fl6))
			goto neigh;
		break;
	default:
		return;
	}

	n = dst_neigh_lookup(rt_dst_entry, pkey);
	if (!n) {
		dst_release(rt_dst_entry);
		goto neigh;
	}

	neigh_ha_snapshot(addr, n, netdev);
	ether_addr_copy(dst, addr);
	if (attrs->dir == XFRM_DEV_OFFLOAD_OUT &&
	    is_zero_ether_addr(addr))
		neigh_event_send(n, NULL);
	dst_release(rt_dst_entry);
	neigh_release(n);
	return;

neigh:
	n = neigh_lookup(&arp_tbl, pkey, netdev);
	if (!n) {
		n = neigh_create(&arp_tbl, pkey, netdev);
		if (IS_ERR(n))
			return;
		neigh_event_send(n, NULL);

Annotation

Implementation Notes