Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dhcpcd InfiniBand support #4830

Merged
merged 2 commits into from
Feb 11, 2024
Merged

Conversation

holmanb
Copy link
Member

@holmanb holmanb commented Jan 30, 2024

Additional Context

Adds InifiniBand support to dhcpcd, updates udhcpc support to use the same client-id as dhcpcd and isc-dhclient.

Context on dhcp with InfiniBand:

InfinBand has its own software stack, but also uses a shim layer, IPoIB, to assign an IP address and provide compatibility with traditional transports (TCP / UDP) over its own transport. Its own transport uses RDMA to transfer data and typical users use a userspace library called libibverbs, on top of which various transports are built.

DHCP -> https://www.rfc-editor.org/rfc/rfc2855
DHCP InfinBand -> https://www.rfc-editor.org/rfc/rfc4390.html
DHCP hwaddr -> https://www.iana.org/assignments/arp-parameters/arp-parameters.txt

Some relevant excerpts from RFC4390:

A DHCP client, when working over an IPoIB interface, MUST follow the
following rules:

"htype" (hardware address type) MUST be 32 [ARPPARAM].

"hlen" (hardware address length) MUST be 0.

"chaddr" (client hardware address) field MUST be zeroed.

"client-identifier" option MUST be used in DHCP messages.

The "client identifier" used in DHCP messages MUST conform to
[RFC4361].

The htype of 32 is the reason for setting "20" for udhcpc:

>>> int("20", base=16)
32

The "chaddr" field is 16 octets in length. The IPoIB link-layer
address is 20 octets in length [RFC4391]. Therefore, the IPoIB
link-layer address will not fit in the "chaddr" field

An InfiniBand address is longer than the required address.

The DHCP protocol states that the "client identifier" option may be
used as the unique identifying value for the client [RFC2132]. This
value must be unique within the client's subnet.

The purpose of the client id is to provide a unique identifier within the subnet.

The "client identifier" option includes a type and identifier pair.
The identifier included in the "client identifier" option may consist
of a hardware address or any other unique value such as the DNS name
of the client.

A client id is a type & unique identifier.

Matching implementation

The importance of client id is to provide a unique identifier to the dhcp server. Therefore, diverging implementations in cloud-init dhcp clients could cause a collision that would be problematic if say, an Alpine instance using udhcpc and an Ubuntu instance using dhcpcd or isc-dhclient on the same subnet report the same client id. The udhcpc code uses get_ib_interface_hwaddr(), which is implemented as:

def get_ib_interface_hwaddr(ifname, ethernet_format):
    """Returns the string value of an Infiniband interface's hardware
    address. If ethernet_format is True, an Ethernet MAC-style 6 byte
    representation of the address will be returned.
    """
    # Type 32 is Infiniband.
    if read_sys_net_safe(ifname, "type") == "32":
        mac = get_interface_mac(ifname)
        if mac and ethernet_format:
            # Use bytes 13-15 and 18-20 of the hardware address.
            mac = mac[36:-14] + mac[51:]
        return mac

This diverges from the isc-dhclient implementation which uses get_interface_mac(interface)[36:]. The change in udhcpc is to ensure that a collision like this wouldn't occur.

Test Steps

tox -e py3

Merge type

  • Squash merge using "Proposed Commit Message"
  • Rebase and merge unique commits. Requires commit messages per-commit each referencing the pull request number (#<PR_NUM>)

@holmanb holmanb changed the title Holmanb/dhcpcd infiniband dhcpcd infiniband support Jan 30, 2024
@holmanb
Copy link
Member Author

holmanb commented Jan 30, 2024

@wmousa I'm reaching out to you since proposed the original isc-dhclient InfiniBand PR in cloud-init to support OpenStack VMs. Since isc-dhclient is no longer supported upstream, cloud-init has added support for udhcpc and more recently dhcpcd to enable cloud-init to use a currently supported dhcp client.

Could you please review the proposed changes or help put us in contact with someone at Mellanox / Nvidia who might be willing to review and test? Unfortunately we lack hardware to test this on.

@holmanb holmanb changed the title dhcpcd infiniband support dhcp InfiniBand support Jan 30, 2024
@holmanb holmanb changed the title dhcp InfiniBand support dhcpcd InfiniBand support Feb 1, 2024
Copy link
Member

@TheRealFalcon TheRealFalcon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be nice if we could get confirmation this works as expected, but I'm not sure how long we should wait for.

@holmanb holmanb force-pushed the holmanb/dhcpcd-infiniband branch from 9dc9c75 to 2aa9884 Compare February 9, 2024 15:01
Dhcpcd will default to sending a default of hardware family and hardware
address when no argument is given. Since this is the required behavior for dhcp
on InfiniBand, use this flag if an InfiniBand interface is detected.

from dhcpcd(8):

-I, --clientid clientid

       Send the clientid. If the string is of the format 01:02:03 then it is
       encoded as hex. For interfaces whose hardware address is longer than 8
       bytes, or if the clientid is an empty string then dhcpcd sends a
       default clientid of the hardware family and the hardware address.
Currently it uses the OpenStack codepath which grabs some random bytes out of
the hardware address.
@holmanb holmanb force-pushed the holmanb/dhcpcd-infiniband branch from 2aa9884 to c975a24 Compare February 9, 2024 15:02
@holmanb
Copy link
Member Author

holmanb commented Feb 9, 2024

I just pushed to merge test conflicts.

It'd be nice if we could get confirmation this works as expected, but I'm not sure how long we should wait for.

+1 I'd rather include this now - in theory it should work, and if not then at least we tried and we can iterate if testers with InfiniBand hardware show up.

@TheRealFalcon
Copy link
Member

I'd rather include this now

+1 to merge

@holmanb holmanb merged commit c608a9c into canonical:main Feb 11, 2024
29 checks passed
holmanb added a commit that referenced this pull request Feb 11, 2024
Dhcpcd will default to sending a default of hardware family and hardware
address when no argument is given. Since this is the required behavior for dhcp
on InfiniBand, use this flag if an InfiniBand interface is detected.

from dhcpcd(8):

-I, --clientid clientid

       Send the clientid. If the string is of the format 01:02:03 then it is
       encoded as hex. For interfaces whose hardware address is longer than 8
       bytes, or if the clientid is an empty string then dhcpcd sends a
       default clientid of the hardware family and the hardware address.
blackboxsw pushed a commit that referenced this pull request Feb 15, 2024
Dhcpcd will default to sending a default of hardware family and hardware
address when no argument is given. Since this is the required behavior for dhcp
on InfiniBand, use this flag if an InfiniBand interface is detected.

from dhcpcd(8):

-I, --clientid clientid

       Send the clientid. If the string is of the format 01:02:03 then it is
       encoded as hex. For interfaces whose hardware address is longer than 8
       bytes, or if the clientid is an empty string then dhcpcd sends a
       default clientid of the hardware family and the hardware address.
blackboxsw pushed a commit that referenced this pull request Feb 15, 2024
Currently it uses the OpenStack codepath which grabs some random bytes out of
the hardware address.
blackboxsw pushed a commit that referenced this pull request Feb 15, 2024
Dhcpcd will default to sending a default of hardware family and hardware
address when no argument is given. Since this is the required behavior for dhcp
on InfiniBand, use this flag if an InfiniBand interface is detected.

from dhcpcd(8):

-I, --clientid clientid

       Send the clientid. If the string is of the format 01:02:03 then it is
       encoded as hex. For interfaces whose hardware address is longer than 8
       bytes, or if the clientid is an empty string then dhcpcd sends a
       default clientid of the hardware family and the hardware address.
blackboxsw pushed a commit that referenced this pull request Feb 15, 2024
Currently it uses the OpenStack codepath which grabs some random bytes out of
the hardware address.
blackboxsw pushed a commit that referenced this pull request Feb 16, 2024
Dhcpcd will default to sending a default of hardware family and hardware
address when no argument is given. Since this is the required behavior for dhcp
on InfiniBand, use this flag if an InfiniBand interface is detected.

from dhcpcd(8):

-I, --clientid clientid

       Send the clientid. If the string is of the format 01:02:03 then it is
       encoded as hex. For interfaces whose hardware address is longer than 8
       bytes, or if the clientid is an empty string then dhcpcd sends a
       default clientid of the hardware family and the hardware address.
blackboxsw pushed a commit that referenced this pull request Feb 16, 2024
Currently it uses the OpenStack codepath which grabs some random bytes out of
the hardware address.
blackboxsw pushed a commit that referenced this pull request Feb 16, 2024
Dhcpcd will default to sending a default of hardware family and hardware
address when no argument is given. Since this is the required behavior for dhcp
on InfiniBand, use this flag if an InfiniBand interface is detected.

from dhcpcd(8):

-I, --clientid clientid

       Send the clientid. If the string is of the format 01:02:03 then it is
       encoded as hex. For interfaces whose hardware address is longer than 8
       bytes, or if the clientid is an empty string then dhcpcd sends a
       default clientid of the hardware family and the hardware address.
blackboxsw pushed a commit that referenced this pull request Feb 16, 2024
Currently it uses the OpenStack codepath which grabs some random bytes out of
the hardware address.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants