IPoIB: the management plane on an IB fabric
S1·E4The tenant network that comes up and answers nothing · Customer PoC cage, two days before acceptance
Builds on: LIDs, GIDs, GUIDs and LMC
Before you read: what do you already know?
3 quick questions. Wrong answers are fine and expected; trying first makes the lesson stick.
After this lesson you can
- Describe the IPoIB encapsulation and the 20-octet hardware address from RFC 4391 and say why ARP needs a hardware type of its own.
- Create and remove an IPoIB child interface for a partition and predict its name and PKey.
- Compute the IPoIB MTU for a given fabric MTU in datagram mode and state what connected mode changes.
- Write a partitions.conf stanza that will actually produce a working IPoIB interface and name the two mistakes that produce an interface that comes up but never resolves ARP.
Episode 4 — The tenant network that comes up and answers nothing
The pod itself is fine. RDMA benchmarks run at the expected rate, the subnet manager is quiet, one master now, and everything the fabric was bought for works. What does not work is the tenant network the demo rides on: the scheduler, every ssh session. The platform team declared a partition for it, the interface duly appeared on all three hosts, they configured addresses, and nothing reaches anything. The interface is up. It resolves no ARP.
Their storage engineer is downloading a different driver version. The network lead, notebook half full, says show me the counter that makes this the fabric’s fault. You ask instead for the subnet manager’s partition file and for cat /sys/class/net/ib0/pkey from one host.
IPoIB exists because a fabric bought for RDMA still has to carry everything that is not RDMA — ssh, the scheduler, in-band management on the default PKey[9] — and because SHARP itself requires an enabled IPoIB interface on the compute servers in order to use UD multicast for result distribution.[7] The Linux driver is native in the sense of setting the interface type to ARPHRD_INFINIBAND and the hardware address length to 20, so the link layer really is InfiniBand and only the payload is IP.[2] Which means the parts failing here are InfiniBand parts: a broadcast group and a membership bit, both owned by the subnet manager rather than by the host.[5]
When IPoIB comes up and resolves nothing, stop reading the host and read the partition.
Start with what the driver creates, and where it gets its PKey.
1A native driver, not a tunnel
IPoIB is easy to under-estimate as “IP in a tunnel over RDMA”. It is not. The Linux driver is “an implementation of the IP over InfiniBand protocol as specified by RFC 4391 and 4392… It is a ‘native’ implementation in the sense of setting the interface type to ARPHRD_INFINIBAND and the hardware address length to 20”.[2] The link layer really is InfiniBand; only the payload is IP.
That 20-octet hardware address is [8-bit reserved][24-bit QPN][128-bit GID], and RFC 4391 recommends “that the GID formed by the combination of the IB subnet prefix and the port’s ‘Port GUID’ be included in the link-layer/hardware address”.[1] Two consequences follow immediately. First, the address contains a queue-pair number, because delivery on InfiniBand is to a QP and not to a port. Second, ARP cannot reuse Ethernet’s parameters: RFC 4391 section 9.2 states that for IPv4 the ARP hardware type is 32 and “The length of the hardware address used in ARP packet header therefore is 20”.[1]
Every datagram carries a small header of its own: “All IP and ARP datagrams transported over InfiniBand are prefixed by a 4-octet encapsulation header”, whose Reserved field “MUST be set to zero on send and ignored on receive”.[1] Remember that 4 - it is the entire explanation for the MTU arithmetic two segments from now.
Why any of this matters on a fabric bought for RDMA: everything that is not an RDMA application still needs IP. On an InfiniBand-only pod that is ssh, the scheduler, monitoring, and - specifically - SHARP, which requires “Enabled IPoIB interface in compute servers in order to enable using UD multicast for result distribution”.[7] MLNX-OS makes the same point from the switch side: “IP interface ‘ib0’ is running under the default PKEY (0x7fff) and can be used for in-band management connectivity to the system.”[9]
2One interface per port, and children per partition
“When the IPoIB driver is loaded, it creates one interface for each port using the P_Key at index 0.”[2] That single sentence decides your naming and your tenancy model. The base ib0 belongs to whatever partition occupies block 0, index 0 of the port’s PKey table - by default the default partition 0x7fff.[9][5]
Additional partitions get child interfaces, created and destroyed through sysfs:
echo 0x8001 > /sys/class/net/ib0/create_child # creates ib0.8001 with P_Key 0x8001
echo 0x8001 > /sys/class/net/ib0/delete_child # removes itBoth lines are quoted from the kernel documentation.[2] The pkey and parent sysfs files expose the mapping afterwards, and “Child interface create/delete can also be done using IPoIB’s rtnl_link_ops, where children created using either way behave the same”.[2]
Which partition lands at index 0 is controlled from the subnet manager, not the host. In partitions.conf, indx0 “indicates that this pkey should be inserted in block 0 index 0”.[5] So if a customer wants their tenant partition to be the base ib0 rather than a child, that is a one-token change in the SM’s partition file - and it changes what the default partition’s interface is called on every host at once.[5]
* = inherited from defmember.- warntenant-a: empty port list — "Empty list means no ports in this partition."Definition: [PartitionName][=PKey][,indx0][,ipoib_bc_flags][,defmember=full|limited] then " : " a port-GUID list and " ; ". Keywords: ALL, ALL_CAS, ALL_SWITCHES, ALL_ROUTERS, SELF (the subnet manager's port). "Empty list means no ports in this partition."
"defmember=full|limited|both — specifies default membership for port guid list. Default is limited." A GUID written without "=full" inherits it; an unrecognised suffix is also read as limited.
"indx0 — indicates that this pkey should be inserted in block 0 index 0." That slot is what the IPoIB driver reads: it "creates one interface for each port using the P_Key at index 0".
FAE angle. Three lines of answer: own PKey 0x7ff1 with defmember=full inside the tenant, limited membership on 0x7fff outside it, part_enforce=both so the leaf switch drops the mismatch instead of trusting the HCA.
Switch-embedded SM (MLNX-OS): ib partition my-partition pkey 0x7ff2 → partition my-partition → member all; read back with show ib partition. It applies "only when the SM is enabled and running on the system."
# /etc/opensm/partitions.conf — opensm -P /etc/opensm/partitions.conf -Z both Default=0x7fff,ipoib,defmember=full : ALL=full, SELF=full ; tenant-a=0x7ff1,indx0,ipoib,mtu=5,defmember=full : ;
Definition: [PartitionName][=PKey][,indx0][,ipoib_bc_flags][,defmember=full|limited] then " : " a port-GUID list and " ; ". Keywords: ALL, ALL_CAS, ALL_SWITCHES, ALL_ROUTERS, SELF (the subnet manager's port). "Empty list means no ports in this partition."
"The following rule is equivalent to how OpenSM used to run prior to the partition manager: Default=0x7fff,ipoib:ALL=full;"
3Datagram or connected: the MTU arithmetic
“The mode is set and read through an interface’s /sys/class/net/<intf name>/mode file.”[2] There are two.
Datagram mode uses the IB unreliable-datagram transport, and “the interface MTU has is equal to the IB L2 MTU minus the IPoIB encapsulation header (4 bytes).”[2] On a typical 2K fabric that is 2048 - 4 = 2044 bytes, which RFC 4391 makes the floor for every implementation: the IB components “may support maximum payloads of 256, 512, 1024, 2048, or 4096 octets… this document requires that all IPoIB implementations support an MTU of 2044 octets”.[1]
Connected mode “takes advantage of the connected nature of the IB transport and allows an MTU up to the maximal IP packet size of 64K.”[2] Two caveats travel with it and both matter operationally: “In connected mode, the interface’s UD QP is still used for multicast and communication with peers that don’t support connected mode”, and “Stateless offloads are supported only in datagram mode.”[2] So connected mode is a large-message optimisation that keeps a datagram path underneath it, and it costs you the offloads.
NVIDIA’s DOCA page adds the numbers a Dell customer will actually hit: IPoIB supports “Varies MTU values: up to 4k in Datagram mode”, the physical port MTU defaults to 4k while “the IPoIB logical MTU defaults to 2k”, and in OpenSM partition files you use “mtu=5 for 4k and mtu=4 for 2k”.[3] The same page describes Enhanced IPoIB, which “enables offloading ULP basic capabilities to a lower vendor specific driver, in order to optimize IPoIB data path” with stateless offloads, multiple queues and interrupt moderation - and is UD mode only.[3]
The trap in one line: the partition file’s mtu= default is 4, meaning 2048, so a host configured for 4092 or 65520 will look up and behave broken until someone compares the two.[5][3]
4The partition side: where a working IPoIB interface actually comes from
An IPoIB interface needs a multicast broadcast group to exist before ARP can work, and that group is created by the subnet manager, not by the host. In partitions.conf the ipoib flag “indicates that this partition may be used for IPoIB, as a result the IPoIB broadcast group will be created with the mgroup_flag flags given, if any”.[5] The flags default to rate=3 (10 Gbps), mtu=4 (2048), sl=0, scope=2 (link local), Q_Key=0x0b1b for IP groups, TClass=0 and FlowLabel=0.[5] One of them carries an explicit warning: “WARNING: changing this [Q_Key] for the broadcast group may break IPoIB on client nodes!!!”[5]
Membership is the second half. P_Key bit 15 is the membership bit - “‘1’ means full member, ‘0’ means limited member” - and “A P_Key match occurs only if at least one of the nodes (sending / receiving) is a full member”.[6] RFC 4391 turns that into a requirement for IPoIB specifically: “a ‘Full Membership’ P_Key (high-order bit is set to 1) MUST be used so that all members may communicate with one another”, and every IPoIB interface “MUST ‘FullMember’ join the IB multicast group defined by the broadcast-GID”.[1]
Now put it beside the partition-file default: defmember “specifies default membership for port guid list. Default is limited.”[5] So a stanza written without =full produces limited members, the broadcast group cannot be full-member joined by them, and the interface comes up and resolves nothing. Two limited members of the same partition also cannot reach each other - that follows from the match rule quoted above, though note that the OpenSM man page never spells out the limited-to-limited case verbatim; the closest primary statement is RFC 4391’s full-membership requirement.[6][1]
The canonical known-good one-liner is worth keeping in a snippet file: Default=0x7fff,ipoib:ALL=full; - “equivalent to how OpenSM used to run prior to the partition manager”.[5] And on the QoS side, OpenSM matches IPoIB traffic by PKey: ipoib :, ipoib, pkey 0x7fff : and any, pkey 0x7fff : are equivalent match rules.[8]
Requirement. A tenant needs its own IPoIB network on PKey 0x8001, at 4K MTU, on three hosts whose port GUIDs are 0x0002c90300a1b2c1, …c2 and …c3. The default partition must remain usable for in-band management.
Step 1 - keep Default explicit. The moment a partition file exists, every port that has no Default rule drops to limited membership, so the Default stanza is not optional even though it looks like boilerplate.[5]
Default=0x7fff, ipoib : ALL=full ;Step 2 - write the tenant stanza with full membership and the ipoib flag. The grammar is [PartitionName][=PKey][,indx0][,ipoib_bc_flags][,defmember=full|limited] followed by a port-GUID list.[5]
tenant-a=0x8001, ipoib, mtu=5, defmember=full : 0x0002c90300a1b2c1, 0x0002c90300a1b2c2, 0x0002c90300a1b2c3 ;mtu=5 asks for a 4K multicast group per NVIDIA’s pairing; defmember=full overrides the documented default of limited; ipoib is what creates the broadcast group at all.[3][5]
Step 3 - predict the result before touching a host. Only the low 15 bits of the PKey are used, so 0x8001 is the partition value and full members will see it in their PKey table with bit 15 set.[5][6] The child interface will be named ib0.8001.[2] Its datagram-mode MTU will be the IB L2 MTU minus 4 - so 4092 if the fabric really carries 4K, and 2044 if anything in the path is still 2K.[2][1]
Step 4 - create it and verify.
echo 0x8001 > /sys/class/net/ib0/create_child
cat /sys/class/net/ib0.8001/pkey
ip -d link show ib0.8001Expected: pkey reads 0x8001, the link shows link/infiniband with a 20-byte address, and the MTU matches your prediction.[2][1] Rollback: echo 0x8001 > /sys/class/net/ib0/delete_child.[2]
Requirement. A second tenant on PKey 0x8002 must be the partition that the base ib0 interface uses on its hosts, at 2K MTU, with two member GUIDs 0x…d1 and 0x…d2.
Fill in the blanks:
Default=0x7fff, ipoib : ALL=____ ;
tenant-b=0x8002, ______, ______, defmember=______ : 0x…d1, 0x…d2 ;- The flag that makes this partition the one at block 0 index 0 is ____________, and it matters because the driver ____________.
- The mtu token for a 2K group is ____________ - and it is also the ____________ if you write nothing.
- On the member hosts the interface carrying this partition will be called ____________, not
ib0.8002. - If you had written
defmember=limitedhere, the observable symptom would be ____________, and the reason is ____________.
Problem - solve alone. A customer has one IB fabric, a storage vendor that wants its own isolated network, and a compute tenant. They send you their current file:
storage=0x7ff2 : 0x0002c90300b00001, 0x0002c90300b00002 ;
compute=0x7ff3, ipoib : ALL_CAS ;Produce:
- A per-port membership prediction for a compute node that appears in neither GUID list, with the exact sentence from the documentation that justifies it.
- Every reason this file will not give either tenant a working IPoIB interface - there is more than one.
- A corrected file that gives storage a non-IPoIB isolated partition, gives compute a working IPoIB partition at 4K, and leaves
0x7fffusable for in-band management. - The three commands you would run on one compute host to prove the result, and the expected output of each.
Acceptance criteria: your prediction quotes the Default-rule asymmetry; your corrected file includes an explicit Default stanza; every membership you rely on is stated rather than defaulted; and your verification includes at least one read from sysfs and one read from the fabric side.
Episode 4 — One token, before lunch
The tenant stanza was written without =full, and defmember “specifies default membership for port guid list. Default is limited.”[5] RFC 4391 requires a full-membership P_Key so that all members may communicate with one another, and requires every IPoIB interface to FullMember-join the multicast group defined by the broadcast-GID.[1] So the interface came up, joined nothing it could use, and answered no ARP. What you say to the platform team: “The host was never the problem. Your partition made every one of those ports a limited member, and limited members have nobody to talk to.” Two days later, at 09:00 on acceptance day, twelve of the sixty-four nodes fail the customer’s script — and a technician is already in the aisle with a card in his hand.
Lab
Mutating. Step 5 creates a child interface and step 7 changes the IPoIB mode. Both name their rollback. Do this on a Dell-lab host only, never on a host carrying customer traffic.
- Pre-flight inventory - capture this before anything:
ip -d link show ib0 > /tmp/ipoib-before.txt,cat /sys/class/net/ib0/{pkey,mode},ibstat, andls /sys/class/net/ | grep ^ib. Expected: oneib0, apkeyof0x7fffon a default fabric, and amodeofdatagramorconnected. - Confirm the interface really is native InfiniBand:
ip -d link show ib0. Expected:link/infinibandfollowed by a 20-byte hardware address, not a 6-byte MAC. If you seelink/ether, this port is in Ethernet mode and this lab does not apply. - Record the MTU and check the arithmetic against the fabric:
ip link show ib0 | grep mtuand compare with the active MTU fromibv_devinfo. Expected: the IPoIB MTU is the IB L2 MTU minus 4 in datagram mode. - Confirm which partition owns the base interface:
cat /sys/class/net/ib0/pkey. Expected: the PKey at index 0 of the port’s table -0x7fffunless your SM’s partition file usesindx0elsewhere. - Mutating. Create a child interface for a PKey your local
opensmactually defines:echo 0x8001 > /sys/class/net/ib0/create_child, thencat /sys/class/net/ib0.8001/{pkey,parent}andip -d link show ib0.8001. Expected: a new interface namedib0.8001withpkey0x8001andparentib0. Rollback:echo 0x8001 > /sys/class/net/ib0/delete_child, then confirm withls /sys/class/net/ | grep ib0that it is gone. - Prove the partition dependency rather than assuming it: create a child for a PKey your SM does not define, and observe that the interface appears and carries no traffic. Expected: creation succeeds locally, connectivity does not exist. Rollback: the matching
delete_child. This is the whole lesson in one observation. - Mutating, optional. Switch the base interface’s mode:
cat /sys/class/net/ib0/modeto record the current value, thenecho connected > /sys/class/net/ib0/mode, re-read the MTU, and note what changed. Expected: the interface can now carry a larger MTU and stateless offloads are no longer in play. Rollback:echo datagram > /sys/class/net/ib0/modeand confirm the MTU returns to the value in/tmp/ipoib-before.txt. Note that the kernel documentation is the source for this file; NVIDIA’s DOCA 3.5.0 IPoIB page does not show it. - Optional, where a peer exists: put an IP on both ends of a partition interface and confirm ARP resolves, then repeat on a partition whose members are limited and observe the difference. Expected: full membership resolves, limited does not. Rollback: remove the addresses you added with
ip addr del.
No InfiniBand hardware. Paper design plus man-page validation - the goal is that your prediction and the documentation disagree in writing before you ever touch a card.
- In a container:
apt-get update && apt-get install -y opensm infiniband-diags man-db. Expected:man opensmopens. The partition grammar lives in that page and inpartition-config.txtfrom the OpenSM source tree. - Write a
partitions.conffrom scratch for a tenant partition with theipoibflag andmtu=5, before reading the reference. Then predict, in writing: the resulting IPoIB MTU in datagram mode, the multicast group’srate,sl,scopeandQ_Key, and the membership every unlisted port ends up with. Expected: you will get at least two of them wrong. - Now read
man opensm(partition section) and mark every default you guessed wrong. Expected:mtudefault 4 not 5,ratedefault 3,scopedefault 2,Q_Keydefault 0x0b1b for IP groups,defmemberdefault limited. - Sketch the 20-byte hardware address for a given QPN and GID from RFC 4391 section 9: write out the reserved octet, the 3-octet QPN and the 16-octet GID as a hex string. Expected: 20 octets exactly. Cross-check the field order against the RFC before you accept your own answer.
- Compute the IPoIB MTU for fabric L2 MTUs of 1024, 2048 and 4096 in datagram mode, and state what each becomes in connected mode. Expected: 1020, 2044, 4092 - and up to 64K in connected mode regardless.
- Validate your file’s syntax without a fabric:
opensm -c /tmp/opensm.confdumps a configuration template you can inspect for the partition-related parameters, andopensm --helpconfirms-P/--Pconfig. Expected: no fabric access needed; this is a syntax and defaults exercise only.
Retrieval check
10 questions from memory. Answer before looking anything up; misses become flashcards.
Explain it to a Dell SE
Explain to a Dell SE, in five sentences, what IPoIB is for on a fabric whose whole point is RDMA, and why the tenant interface they just created came up but cannot ping anything.
Sources
Facts in this lesson were checked against Linux kernel Documentation/infiniband/ipoib.txt re-fetched and re-quoted 2026-09-07 (mode file, create_child/delete_child, datagram and connected MTU, ARPHRD_INFINIBAND, PKey index 0); RFC 4391; DOCA 3.5.0 IP Over InfiniBand; opensm(8) and partition-config.txt (master). Dates are when each page was fetched.
- RFC 4391 - Transmission of IP over InfiniBand (IPoIB) · fetched 2026-09-07
- ipoib.txt - Linux kernel InfiniBand documentation · fetched 2026-09-07
- IP Over InfiniBand - DOCA 3.5.0 · fetched 2026-09-07
- opensm(8) man page source - linux-rdma/opensm master · fetched 2026-09-07
- OpenSM partitions.conf configuration reference · fetched 2026-09-07
- NVIDIA InfiniBand Security Overview and Guidelines - Security in InfiniBand · fetched 2026-09-07
- NVIDIA SHARP 3.8.0 - Setting up NVIDIA SHARP Environment · fetched 2026-09-07
- QoS Management in OpenSM · fetched 2026-09-07
- Subnet Manager - NVIDIA MLNX-OS User Manual v3.12.6200 LTS · fetched 2026-09-07
- RFC 4392 - IP over InfiniBand (IPoIB) Architecture · fetched 2026-09-07
The same idea elsewhere
Other lessons that cover this ground, sometimes from another course's angle.