From nobody Mon Feb 24 00:20:31 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Z1Lww15Plz5pHK9; Mon, 24 Feb 2025 00:20:32 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Z1Lwv4mXJz3bQ1; Mon, 24 Feb 2025 00:20:31 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1740356431; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=TXMGKQQI6/shVrG3IQTJepsj1UcpAkS+IFy+1mROvF0=; b=SNBIFrZ6fDIrHiPZwhkeCHlcWyGRMNaFTRxmNNbppufBi9iofpQ9mN0tJ15wiFAz/RDOuk P35ZTqAaTHt7q2TPgQybBixzxZQ7PQgZbQNGWEboziLbG2iPJRJGhmSoJGcPYl6X2VW3qI MxXknfLMsswlHJGZNbzQaibRJIbUVTt23HNPp8YhcYP5zttkbxVKmVLvdos7q+Ms/iV9RT 1e5XwyqED1GoKpbqykYpx167vsoih3XZNsWXNbbBV2D2CqGdLRT5p/Rzck8HbkVipG7SRz d7ftRtS9B5pOhTLUTtESDHKXg8M6bUYkWRyBKgdX8hyovB6N9cfgG9iAkkAJgQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1740356431; a=rsa-sha256; cv=none; b=f+94r9oqVpEJJjd+qULK8Z815Ac8UKaXMpfz0dZvEt6KIk+hE+f/6ooS4dFnOIsRYWv43r onJBgLhMAj7ZYfKw2O1WqKsMFAhlMRTKCmnOImcAeayUwRwLrb9n+xOhpSyC/YyC6g9/09 HWfTEAO60K1qHCHMkKSBCpdpxNAcbNe0uMh/6nHXSmqrUXcDHGhr3KFo97QAR1VUxAFY0G Cion30o3YC0gvDC1ELvEwcXSqnTfhqCGQLlkJiXCsH+Cd7gwHU+8kzXsRCThsNbdeCe47N 4nihIANib35ULUK3Dmm376hyDze8tIxzxQmCwiVMB8nGu0lsLS7ns4bIqBDKNw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1740356431; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=TXMGKQQI6/shVrG3IQTJepsj1UcpAkS+IFy+1mROvF0=; b=Zlwl/T+cfwXaIiM0O/zbxQp+LKGKN1NNkrpK/Y9cUYF3CpOG9NHeGKc6SGza4Wh9fzF+Pc BG9uDrgoddN1gCKVV9IH/n8cmMpKu0EOaCqieZNKqAJNd7kSuFfuWNCCmRT0m/bi/dxE36 CW4suPyeTQ5pYsCdkIcZcw42MVsr1eivz0eTeB6/KbB8TEl5nzaVziaIAmZUt7eqgLqdn/ 0tpVkMohIteVMv9/UgRZhQxkzxMzITKmV2LmUz54cvF0AMOJOu5l68yRgsDCJUVbJb0ae6 i4dMvJyy5ApaXWK0cEl1J4kF5sP30LtrnsadZ9D3PqNGkaOCU7R2uVkGW7/beQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Z1Lwv4C4Cz2Xb; Mon, 24 Feb 2025 00:20:31 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 51O0KVXK074752; Mon, 24 Feb 2025 00:20:31 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 51O0KVO1074749; Mon, 24 Feb 2025 00:20:31 GMT (envelope-from git) Date: Mon, 24 Feb 2025 00:20:31 GMT Message-Id: <202502240020.51O0KVO1074749@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Ravi Pokala Subject: git: 8d079c6a9a5d - main - if_infininband: Support BPF write for broadcast frames List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: rpokala X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 8d079c6a9a5dfdc75adaf9bc31f2ee8111b849a1 Auto-Submitted: auto-generated The branch main has been updated by rpokala: URL: https://cgit.FreeBSD.org/src/commit/?id=8d079c6a9a5dfdc75adaf9bc31f2ee8111b849a1 commit 8d079c6a9a5dfdc75adaf9bc31f2ee8111b849a1 Author: Nicholas Dance AuthorDate: 2025-02-05 23:33:20 +0000 Commit: Ravi Pokala CommitDate: 2025-02-24 00:13:09 +0000 if_infininband: Support BPF write for broadcast frames To support DHCP for IPoIB links, DHCP clients and servers require the ability to transmit link-layer broadcasts on the IB interfaces. BPF provides the mechanism for doing this. This change updates the if_infiniband driver to be capable of accepting link-layer broadcast requests via BPF using Ethernet formatted frames (the driver currently registers with BPF as DLT_EN10MB). Only Broadcast frames can reliably be interpreted using the Ethernet header format so detect unicast and multicast frames are rejected if passed in using the Ethernet format. This doesn't impact the ability to support native unicast, broadcast or multicast frames if native infiniband header support is added to BPF at a later date. Further the above, this commit also addresses an issue in the existing code that can result in separation of part of the packet header from the rest of the payload if a BPF write was attempted. This was caused by mbuf preallocation of the infiniband header length regardless of length of the prepend data. Reviewed by: rpokala; Greg Foster Tested by: Greg Foster MFC after: 1 week Sponsored by: Vdura Pull Request: https://github.com/freebsd/freebsd-src/pull/1591 --- sys/net/if_infiniband.c | 57 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/sys/net/if_infiniband.c b/sys/net/if_infiniband.c index 7f0bb02f1687..94492421d962 100644 --- a/sys/net/if_infiniband.c +++ b/sys/net/if_infiniband.c @@ -149,6 +149,43 @@ infiniband_bpf_mtap(struct ifnet *ifp, struct mbuf *mb) mb->m_pkthdr.len += sizeof(*ibh); } +/* + * For clients using BPF to send broadcasts. + * + * This driver binds to BPF as an EN10MB (Ethernet) device type. As such, it is + * expected BPF and BPF users will send frames with Ethernet headers, which + * we'll do our best to handle. We can't resolve non-native unicast or multicast + * link-layer addresses, but we can handle broadcast frames. + * + * phlen is populated with IB header size if ibh was populated, 0 otherwise. + */ +static int +infiniband_resolve_bpf(struct ifnet *ifp, const struct sockaddr *dst, + struct mbuf *mb, const struct route *ro, struct infiniband_header *ibh, + int *phlen) +{ + struct ether_header *eh = (struct ether_header *)ro->ro_prepend; + /* If the prepend data & address length don't have the signature of a frame + * forwarded by BPF, allow frame to passthrough. */ + if (((ro->ro_flags & RT_HAS_HEADER) == 0) || + (ro->ro_plen != ETHER_HDR_LEN)) { + *phlen = 0; + return (0); + } + + /* Looks like this frame is from BPF. Handle broadcasts, reject otherwise */ + if (!ETHER_IS_BROADCAST(eh->ether_dhost)) + return (EOPNOTSUPP); + + memcpy(ibh->ib_hwaddr, ifp->if_broadcastaddr, sizeof(ibh->ib_hwaddr)); + ibh->ib_protocol = eh->ether_type; + mb->m_flags &= ~M_MCAST; + mb->m_flags |= M_BCAST; + + *phlen = INFINIBAND_HDR_LEN; + return (0); +} + static void update_mbuf_csumflags(struct mbuf *src, struct mbuf *dst) { @@ -306,7 +343,7 @@ infiniband_output(struct ifnet *ifp, struct mbuf *m, struct llentry *lle = NULL; struct infiniband_header *ih; int error = 0; - int hlen; /* link layer header length */ + int hlen = 0; /* link layer header length */ uint32_t pflags; bool addref; @@ -316,10 +353,20 @@ infiniband_output(struct ifnet *ifp, struct mbuf *m, phdr = NULL; pflags = 0; if (ro != NULL) { - /* XXX BPF uses ro_prepend */ + /* XXX BPF and ARP use ro_prepend */ if (ro->ro_prepend != NULL) { - phdr = ro->ro_prepend; - hlen = ro->ro_plen; + ih = (struct infiniband_header *)linkhdr; + /* Assess whether frame is from BPF and handle */ + error = infiniband_resolve_bpf(ifp, dst, m, ro, ih, &hlen); + if (error != 0) + goto bad; + + if (hlen != 0) { + phdr = linkhdr; + } else { + phdr = ro->ro_prepend; + hlen = ro->ro_plen; + } } else if (!(m->m_flags & (M_BCAST | M_MCAST))) { if ((ro->ro_flags & RT_LLE_CACHE) != 0) { lle = ro->ro_lle; @@ -386,7 +433,7 @@ infiniband_output(struct ifnet *ifp, struct mbuf *m, * Add local infiniband header. If no space in first mbuf, * allocate another. */ - M_PREPEND(m, INFINIBAND_HDR_LEN, M_NOWAIT); + M_PREPEND(m, hlen, M_NOWAIT); if (m == NULL) { error = ENOBUFS; goto bad;