drivers/infiniband/sw/rxe/rxe_net.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/sw/rxe/rxe_net.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/sw/rxe/rxe_net.c
Extension
.c
Size
18975 bytes
Lines
850
Domain
Driver Families
Bucket
drivers/infiniband
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

if (av->network_type == RXE_NETWORK_TYPE_IPV4) {
			struct in_addr *saddr;
			struct in_addr *daddr;

			saddr = &av->sgid_addr._sockaddr_in.sin_addr;
			daddr = &av->dgid_addr._sockaddr_in.sin_addr;
			dst = rxe_find_route4(qp, net, ndev, saddr, daddr);
		} else if (av->network_type == RXE_NETWORK_TYPE_IPV6) {
			struct in6_addr *saddr6;
			struct in6_addr *daddr6;

			saddr6 = &av->sgid_addr._sockaddr_in6.sin6_addr;
			daddr6 = &av->dgid_addr._sockaddr_in6.sin6_addr;
			dst = rxe_find_route6(qp, net, ndev, saddr6, daddr6);
#if IS_ENABLED(CONFIG_IPV6)
			if (dst)
				qp->dst_cookie =
					rt6_get_cookie((struct rt6_info *)dst);
#endif
		}

		if (dst && (qp_type(qp) == IB_QPT_RC)) {
			dst_hold(dst);
			sk_dst_set(qp->sk->sk, dst);
		}
	}
	return dst;
}

static int rxe_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
{
	struct udphdr *udph;
	struct rxe_dev *rxe;
	struct net_device *ndev = skb->dev;
	struct rxe_pkt_info *pkt = SKB_TO_PKT(skb);

	/* takes a reference on rxe->ib_dev
	 * drop when skb is freed
	 */
	rxe = rxe_get_dev_from_net(ndev);
	if (!rxe && is_vlan_dev(ndev))
		rxe = rxe_get_dev_from_net(vlan_dev_real_dev(ndev));
	if (!rxe)
		goto drop;

	if (skb_linearize(skb)) {
		ib_device_put(&rxe->ib_dev);
		goto drop;
	}

	udph = udp_hdr(skb);
	pkt->rxe = rxe;
	pkt->port_num = 1;
	pkt->hdr = (u8 *)(udph + 1);
	pkt->mask = RXE_GRH_MASK;
	pkt->paylen = be16_to_cpu(udph->len) - sizeof(*udph);

	/* remove udp header */
	skb_pull(skb, sizeof(struct udphdr));

	rxe_rcv(skb);

	return 0;
drop:
	kfree_skb(skb);

	return 0;
}

static struct socket *rxe_setup_udp_tunnel(struct net *net, __be16 port,
					   bool ipv6)
{
	int err;
	struct socket *sock;
	struct udp_port_cfg udp_cfg = { };
	struct udp_tunnel_sock_cfg tnl_cfg = { };

	if (ipv6) {
		udp_cfg.family = AF_INET6;
		udp_cfg.ipv6_v6only = 1;
	} else {
		udp_cfg.family = AF_INET;
	}

	udp_cfg.local_udp_port = port;

	/* Create UDP socket */
	err = udp_sock_create(net, &udp_cfg, &sock);
	if (err < 0)
		return ERR_PTR(err);

Annotation

Implementation Notes