From: Darsey Litzenberger Date: Wed, 9 Oct 2024 19:55:42 +0000 (-0600) Subject: network/dhcp4: add support for ARPHRD_RAWIP and ARPHRD_NONE network interface types X-Git-Tag: v257-rc1~273 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4bc7a54d75bad9599e661465f400d0329d28411d;p=thirdparty%2Fsystemd.git network/dhcp4: add support for ARPHRD_RAWIP and ARPHRD_NONE network interface types This should fix QMI wwan modems, as noted in https://github.com/systemd/systemd/issues/27219 --- diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index cf26bd0e487..7a899669126 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -273,6 +273,35 @@ int sd_dhcp_client_set_mac( assert_return(client, -EINVAL); assert_return(!sd_dhcp_client_is_running(client), -EBUSY); + assert_return(IN_SET(arp_type, ARPHRD_ETHER, ARPHRD_INFINIBAND, ARPHRD_RAWIP, ARPHRD_NONE), -EINVAL); + + static const uint8_t default_eth_bcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + default_eth_hwaddr[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + switch (arp_type) { + case ARPHRD_RAWIP: + case ARPHRD_NONE: + /* Linux cellular modem drivers (e.g. qmi_wwan) present a + * network interface of type ARPHRD_RAWIP(519) or + * ARPHRD_NONE(65534) when in point-to-point mode, but these + * are not valid DHCP hardware-type values. + * + * Apparently, it's best to just pretend that these are ethernet + * devices. Other approaches have been tried, but resulted in + * incompatibilities with some server software. See + * https://lore.kernel.org/netdev/cover.1228948072.git.inaky@linux.intel.com/ + */ + arp_type = ARPHRD_ETHER; + if (addr_len == 0) { + assert_cc(sizeof(default_eth_hwaddr) == ETH_ALEN); + assert_cc(sizeof(default_eth_bcast) == ETH_ALEN); + hw_addr = default_eth_hwaddr; + bcast_addr = default_eth_bcast; + addr_len = ETH_ALEN; + } + break; + } + assert_return(IN_SET(arp_type, ARPHRD_ETHER, ARPHRD_INFINIBAND), -EINVAL); assert_return(hw_addr, -EINVAL); assert_return(addr_len == (arp_type == ARPHRD_ETHER ? ETH_ALEN : INFINIBAND_ALEN), -EINVAL); diff --git a/src/network/networkd-dhcp-common.c b/src/network/networkd-dhcp-common.c index 9f0268d934e..1799d042127 100644 --- a/src/network/networkd-dhcp-common.c +++ b/src/network/networkd-dhcp-common.c @@ -53,8 +53,10 @@ bool link_dhcp_enabled(Link *link, int family) { assert(link); assert(IN_SET(family, AF_INET, AF_INET6)); - /* Currently, sd-dhcp-client supports only ethernet and infiniband. */ - if (family == AF_INET && !IN_SET(link->iftype, ARPHRD_ETHER, ARPHRD_INFINIBAND)) + /* Currently, sd-dhcp-client supports only ethernet and infiniband. + * (ARMHRD_RAWIP and ARMHRD_NONE are typically wwan modems and will be + * treated as ethernet devices.) */ + if (family == AF_INET && !IN_SET(link->iftype, ARPHRD_ETHER, ARPHRD_INFINIBAND, ARPHRD_RAWIP, ARPHRD_NONE)) return false; if (family == AF_INET6 && !socket_ipv6_is_supported())