diff options
author | Sam James <sam@gentoo.org> | 2024-02-18 11:23:52 +0000 |
---|---|---|
committer | Sam James <sam@gentoo.org> | 2024-02-18 11:24:55 +0000 |
commit | becd6aebc7e4c3e78e2497c4315ad2a1df5b3bd1 (patch) | |
tree | ecde29e8e40934cf2ff00b2fe758765e3bcac9a5 /net-misc | |
parent | net-misc/dhcp: add support for Infiniband (diff) | |
download | gentoo-becd6aebc7e4c3e78e2497c4315ad2a1df5b3bd1.tar.gz gentoo-becd6aebc7e4c3e78e2497c4315ad2a1df5b3bd1.tar.bz2 gentoo-becd6aebc7e4c3e78e2497c4315ad2a1df5b3bd1.zip |
net-misc/dhcp: move patches to devspace for 4.4.3_p1-r5
Signed-off-by: Sam James <sam@gentoo.org>
Diffstat (limited to 'net-misc')
-rw-r--r-- | net-misc/dhcp/Manifest | 1 | ||||
-rw-r--r-- | net-misc/dhcp/dhcp-4.4.3_p1-r5.ebuild | 27 | ||||
-rw-r--r-- | net-misc/dhcp/files/dhcp-4.4.3-infiniband.patch | 957 |
3 files changed, 16 insertions, 969 deletions
diff --git a/net-misc/dhcp/Manifest b/net-misc/dhcp/Manifest index 565f763ef590..47b71db74f8f 100644 --- a/net-misc/dhcp/Manifest +++ b/net-misc/dhcp/Manifest @@ -1 +1,2 @@ DIST dhcp-4.4.3-P1.tar.gz 10081055 BLAKE2B 6cc16f7472efb1e1f6b7a83cafd9a81a16f10af7361da079c48a5eff0d9e310f475dcc82e984c20936c64867183402d00d26e5366e75bf7463ec2aea4a6f68a4 SHA512 d14dc44d1c015780ae19769816cb01015959927a1ad7a3e84b89e0463253aaf46451af88e3260347196373906d5b438c7c616fee45ec3f128aa82af6702b7154 +DIST dhcp-4.4.3-patches.tar.xz 15276 BLAKE2B 4750833f986eccdc60b63de55f0b0633039806d75e1bbb79ea6974990399f2ec33836fd22ec3a0981aaeffc3fcfd914deff96d139f4ea3c2ad1b9010ec737d06 SHA512 c8071f48e4074a7a83e74706868a782c7dc4bcb6df4b9035411e419a95bf90de66ece2b2aacc8f8f3ca517287599cb178704402ff276a4620c941733ce03c57b diff --git a/net-misc/dhcp/dhcp-4.4.3_p1-r5.ebuild b/net-misc/dhcp/dhcp-4.4.3_p1-r5.ebuild index 479016e40c64..040aa5192a15 100644 --- a/net-misc/dhcp/dhcp-4.4.3_p1-r5.ebuild +++ b/net-misc/dhcp/dhcp-4.4.3_p1-r5.ebuild @@ -16,6 +16,7 @@ HOMEPAGE="https://www.isc.org/dhcp" SRC_URI=" https://downloads.isc.org/isc/dhcp/${MY_P}.tar.gz https://downloads.isc.org/isc/dhcp/${MY_PV}/${MY_P}.tar.gz + https://dev.gentoo.org/~sam/distfiles/${CATEGORY}/${PN}/dhcp-4.4.3-patches.tar.xz " S="${WORKDIR}/${MY_P}" @@ -50,29 +51,31 @@ BDEPEND=" PATCHES=( # Gentoo patches - these will probably never be accepted upstream # Fix some permission issues - "${FILESDIR}/${PN}-4.4.3-fix-perms.patch" + "${WORKDIR}/dhcp-4.4.3-patches/${PN}-4.4.3-fix-perms.patch" # Enable dhclient to equery NTP servers - "${FILESDIR}/${PN}-4.4.3-dhclient-ntp.patch" - "${FILESDIR}/${PN}-4.4.3-dhclient-resolvconf.patch" + "${WORKDIR}/dhcp-4.4.3-patches/${PN}-4.4.3-dhclient-ntp.patch" + "${WORKDIR}/dhcp-4.4.3-patches/${PN}-4.4.3-dhclient-resolvconf.patch" # Enable dhclient to get extra configuration from stdin - "${FILESDIR}/${PN}-4.4.3-dhclient-stdin-conf.patch" + "${WORKDIR}/dhcp-4.4.3-patches/${PN}-4.4.3-dhclient-stdin-conf.patch" # bug #265531 - "${FILESDIR}/${PN}-4.4.3-nogateway.patch" + "${WORKDIR}/dhcp-4.4.3-patches/${PN}-4.4.3-nogateway.patch" # bug #296921 - "${FILESDIR}/${PN}-4.4.3-quieter-ping.patch" + "${WORKDIR}/dhcp-4.4.3-patches/${PN}-4.4.3-quieter-ping.patch" # bug #437108 - "${FILESDIR}/${PN}-4.4.3-always-accept-4.patch" + "${WORKDIR}/dhcp-4.4.3-patches/${PN}-4.4.3-always-accept-4.patch" # bug #480636 - "${FILESDIR}/${PN}-4.4.3-iproute2-path.patch" + "${WORKDIR}/dhcp-4.4.3-patches/${PN}-4.4.3-iproute2-path.patch" # bug #471142 - "${FILESDIR}/${PN}-4.4.3-bindtodevice-inet6.patch" + "${WORKDIR}/dhcp-4.4.3-patches/${PN}-4.4.3-bindtodevice-inet6.patch" # bug #559832 - "${FILESDIR}/${PN}-4.4.3-ldap-ipv6-client-id.patch" + "${WORKDIR}/dhcp-4.4.3-patches/${PN}-4.4.3-ldap-ipv6-client-id.patch" + # bug #908986 + "${WORKDIR}/dhcp-4.4.3-patches/${PN}-4.4.3-infiniband.patch" # Possible upstream candidates - "${FILESDIR}/${PN}-4.4.3-configure-clang16.patch" + "${WORKDIR}/dhcp-4.4.3-patches/${PN}-4.4.3-configure-clang16.patch" ) src_unpack() { @@ -136,7 +139,7 @@ src_prepare() { binddir=${binddir} GMAKE=${MAKE:-gmake} EOF - eapply -p2 "${FILESDIR}"/${PN}-4.4.3-bind-disable.patch + eapply -p2 "${WORKDIR}"/dhcp-4.4.3-patches/${PN}-4.4.3-bind-disable.patch # Only use the relevant subdirs now that ISC #removed the lib/export structure in bind. sed '/^SUBDIRS/s@=.*$@= isc dns isccfg irs samples@' \ diff --git a/net-misc/dhcp/files/dhcp-4.4.3-infiniband.patch b/net-misc/dhcp/files/dhcp-4.4.3-infiniband.patch deleted file mode 100644 index 6c1489e2a788..000000000000 --- a/net-misc/dhcp/files/dhcp-4.4.3-infiniband.patch +++ /dev/null @@ -1,957 +0,0 @@ -diff -urP a/client/clparse.c b/client/clparse.c ---- a/client/clparse.c 2023-06-21 23:44:22.471212250 -0600 -+++ b/client/clparse.c 2023-06-22 00:07:48.650031050 -0600 -@@ -197,6 +197,7 @@ - /* Requested lease time, used by DHCPv6 (DHCPv4 uses the option cache) - */ - top_level_config.requested_lease = 7200; -+ top_level_config.bootp_broadcast_always = 0; - - group_allocate (&top_level_config.on_receipt, MDL); - if (!top_level_config.on_receipt) -@@ -460,7 +461,8 @@ - interface-declaration | - LEASE client-lease-statement | - ALIAS client-lease-statement | -- KEY key-definition */ -+ KEY key-definition | -+ BOOTP_BROADCAST_ALWAYS */ - - void parse_client_statement (cfile, ip, config) - struct parse *cfile; -@@ -884,6 +886,12 @@ - break; - - -+ case BOOTP_BROADCAST_ALWAYS: -+ token = next_token(&val, (unsigned*)0, cfile); -+ config -> bootp_broadcast_always = 1; -+ parse_semi (cfile); -+ return; -+ - default: - lose = 0; - stmt = (struct executable_statement *)0; -diff -urP a/client/dhclient.c b/client/dhclient.c ---- a/client/dhclient.c 2023-06-21 23:44:22.488212252 -0600 -+++ b/client/dhclient.c 2023-06-22 00:07:48.650031050 -0600 -@@ -53,6 +53,13 @@ - - static void add_to_tail(struct client_lease** lease_list, struct client_lease* lease); - -+/* Default Prefix */ -+static unsigned char default_prefix[12] = { -+ 0xff, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x02, 0x00, -+ 0x00, 0x02, 0xc9, 0x00 -+}; -+ - /* False (default) => we write and use a pid file */ - isc_boolean_t no_pid_file = ISC_FALSE; - -@@ -76,6 +83,8 @@ - assert (state_is == state_shouldbe). */ - #define ASSERT_STATE(state_is, state_shouldbe) {} - -+static void setup_ib_interface(struct interface_info *ip); -+ - #ifndef UNIT_TEST - static const char copyright[] = "Copyright 2004-2022 Internet Systems Consortium."; - static const char arr [] = "All rights reserved."; -@@ -821,6 +830,26 @@ - } - } - -+ /* We create a backup seed before rediscovering interfaces in order to -+ have a seed built using all of the available interfaces -+ It's interesting if required interfaces doesn't let us defined -+ a really unique seed due to a lack of valid HW addr later -+ (this is the case with DHCP over IB) -+ We only use the last device as using a sum could broke the -+ uniqueness of the seed among multiple nodes -+ */ -+ unsigned backup_seed = 0; -+ for (ip = interfaces; ip; ip = ip -> next) { -+ int junk; -+ if ( ip -> hw_address.hlen <= sizeof seed ) -+ continue; -+ memcpy (&junk, -+ &ip -> hw_address.hbuf [ip -> hw_address.hlen - -+ sizeof seed], sizeof seed); -+ backup_seed = junk; -+ } -+ -+ - /* At this point, all the interfaces that the script thinks - are relevant should be running, so now we once again call - discover_interfaces(), and this time ask it to actually set -@@ -832,6 +861,7 @@ - /* PLEASE PREFER the random device: not all systems use random - * process identifiers so the alternative can be predictable. */ - seed = 0; -+ int seed_flag = 0; - size_t nrnd = 0; - #ifdef ISC_PATH_RANDOMDEV - FILE *frnd = fopen(ISC_PATH_RANDOMDEV, "r"); -@@ -851,15 +881,42 @@ - - for (ip = interfaces; ip; ip = ip->next) { - int junk; -+ if ( ip -> hw_address.hlen <= sizeof seed ) -+ continue; - memcpy(&junk, - &ip->hw_address.hbuf[ip->hw_address.hlen - - sizeof seed], sizeof seed); - seed += junk; -+ seed_flag = 1; - } - seed += cur_time + (unsigned)getpid(); - } -+ if ( seed_flag == 0 ) { -+ if ( backup_seed != 0 ) { -+ seed = backup_seed; -+ log_info ("xid: rand init seed (0x%x) built using all" -+ " available interfaces",seed); -+ } -+ else { -+ seed = cur_time^((unsigned) gethostid()) ; -+ log_info ("xid: warning: no netdev with useable HWADDR" -+ " found for seed's uniqueness enforcement"); -+ log_info ("xid: rand init seed (0x%x) built using" -+ " gethostid", seed); -+ } -+ /* we only use seed and no current time as a broadcast reply */ -+ /* will certainly be used by the hwaddrless interface */ -+ } - srandom(seed); - -+ /* Setup specific Infiniband options */ -+ for (ip = interfaces; ip; ip = ip->next) { -+ if (ip->client && -+ (ip->hw_address.hbuf[0] == HTYPE_INFINIBAND)) { -+ setup_ib_interface(ip); -+ } -+ } -+ - /* - * Establish a default DUID. We always do so for v6 and - * do so if desired for v4 via the -D or -i options -@@ -1154,6 +1211,66 @@ - return 0; - } - -+static void setup_ib_interface(struct interface_info *ip) -+{ -+ struct group *g; -+ struct hardware *hw = &ip->hw_address; -+ char client_id[64]; -+ char *arg_conf = NULL; -+ int arg_conf_len = 0; -+ isc_result_t status; -+ struct parse *cfile = (struct parse *)0; -+ -+ /* Set the broadcast flag */ -+ ip->client->config->bootp_broadcast_always = 1; -+ -+ /* -+ * Find out if a dhcp-client-identifier option was specified either -+ * in the config file or on the command line -+ */ -+ for (g = ip->client->config->on_transmission; g != NULL; g = g->next) { -+ if ((g->statements != NULL) && -+ (strcmp(g->statements->data.option->option->name, -+ "dhcp-client-identifier") == 0)) { -+ return; -+ } -+ } -+ -+ /* -+ * No client ID specified, make up one based on a default -+ * "prefix" and the port GUID. -+ * -+ * NOTE: This is compatible with what gpxe does. -+ */ -+ sprintf(client_id, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", -+ default_prefix[0], default_prefix[1], default_prefix[2], -+ default_prefix[3], default_prefix[4], default_prefix[5], -+ default_prefix[6], default_prefix[7], default_prefix[8], -+ default_prefix[9], default_prefix[10], default_prefix[11], -+ hw->hbuf[1], hw->hbuf[2], hw->hbuf[3], hw->hbuf[4], -+ hw->hbuf[5], hw->hbuf[6], hw->hbuf[7], hw->hbuf[8]); -+ -+ arg_conf_len = asprintf(&arg_conf, -+ "send dhcp-client-identifier %s;", -+ client_id); -+ -+ if ((arg_conf == 0) || (arg_conf_len <= 0)) -+ log_fatal("Unable to send option dhcp-client-identifier"); -+ -+ status = new_parse(&cfile, -1, arg_conf, arg_conf_len, -+ "Automatic Infiniband client identifier", 0); -+ -+ if ((status != ISC_R_SUCCESS) || (cfile->warnings_occurred)) -+ log_fatal("Failed to parse Infiniband client identifier"); -+ -+ parse_client_statement(cfile, NULL, ip->client->config); -+ -+ if (cfile->warnings_occurred) -+ log_fatal("Failed to parse Infiniband client identifier"); -+ -+ end_parse(&cfile); -+} -+ - /* Individual States: - * - * Each routine is called from the dhclient_state_machine() in one of -@@ -1367,7 +1484,6 @@ - struct client_state *client = cpp; - struct client_lease *lp, *next, *picked; - -- - ASSERT_STATE(state, S_SELECTING); - - /* -@@ -1483,9 +1599,10 @@ - return; - } - -- log_info ("DHCPACK of %s from %s", -+ log_info ("DHCPACK of %s from %s (xid=0x%x)", - inet_ntoa(packet->raw->yiaddr), -- piaddr (packet->client_addr)); -+ piaddr (packet->client_addr), -+ ntohl(client -> xid)); - - /* Check v6only first. */ - v6only_wait = check_v6only(packet, client); -@@ -2439,7 +2556,7 @@ - return; - } - -- log_info ("DHCPNAK from %s", piaddr (packet -> client_addr)); -+ log_info ("DHCPNAK from %s (xid=0x%x)", piaddr (packet -> client_addr), ntohl(client -> xid)); - - if (!client -> active) { - #if defined (DEBUG) -@@ -2572,10 +2689,11 @@ - (long)(client -> interval)); - } else - #endif -- log_info ("DHCPDISCOVER on %s to %s port %d interval %ld", -+ log_info ("DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)", - client -> name ? client -> name : client -> interface -> name, - inet_ntoa (sockaddr_broadcast.sin_addr), -- ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval)); -+ ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval), -+ ntohl(client -> xid)); - - /* Send out a packet. */ - #if defined(DHCPv6) && defined(DHCP4o6) -@@ -2969,10 +3087,10 @@ - } - - strncpy(rip_buf, rip_str, sizeof(rip_buf)-1); -- log_info ("DHCPREQUEST for %s on %s to %s port %d", rip_buf, -+ log_info ("DHCPREQUEST for %s on %s to %s port %d (xid=0x%x)", rip_buf, - client->name ? client->name : client->interface->name, - inet_ntoa(destination.sin_addr), -- ntohs (destination.sin_port)); -+ ntohs (destination.sin_port), client -> xid); - - #if defined(DHCPv6) && defined(DHCP4o6) - if (dhcpv4_over_dhcpv6) { -@@ -3029,11 +3147,11 @@ - log_info ("DHCPDECLINE"); - } else - #endif -- log_info ("DHCPDECLINE of %s on %s to %s port %d", -+ log_info ("DHCPDECLINE of %s on %s to %s port %d (xid=0x%x)", - piaddr(client->requested_address), - (client->name ? client->name : client->interface->name), - inet_ntoa(sockaddr_broadcast.sin_addr), -- ntohs(sockaddr_broadcast.sin_port)); -+ ntohs(sockaddr_broadcast.sin_port), client -> xid); - - /* Send out a packet. */ - #if defined(DHCPv6) && defined(DHCP4o6) -@@ -3092,11 +3210,11 @@ - log_info ("DHCPRELEASE"); - } else - #endif -- log_info ("DHCPRELEASE of %s on %s to %s port %d", -+ log_info ("DHCPRELEASE of %s on %s to %s port %d (xid=0x%x)", - piaddr(client->active->address), - client->name ? client->name : client->interface->name, - inet_ntoa (destination.sin_addr), -- ntohs (destination.sin_port)); -+ ntohs (destination.sin_port), client -> xid); - - #if defined(DHCPv6) && defined(DHCP4o6) - if (dhcpv4_over_dhcpv6) { -@@ -3472,7 +3590,8 @@ - client -> packet.xid = random (); - client -> packet.secs = 0; /* filled in by send_discover. */ - -- if (can_receive_unicast_unconfigured (client -> interface)) -+ if ((!(client->config->bootp_broadcast_always)) -+ && can_receive_unicast_unconfigured(client->interface)) - client -> packet.flags = 0; - else - client -> packet.flags = htons (BOOTP_BROADCAST); -@@ -3557,7 +3676,8 @@ - } else { - memset (&client -> packet.ciaddr, 0, - sizeof client -> packet.ciaddr); -- if (can_receive_unicast_unconfigured (client -> interface)) -+ if ((!(client ->config->bootp_broadcast_always)) && -+ can_receive_unicast_unconfigured (client -> interface)) - client -> packet.flags = 0; - else - client -> packet.flags = htons (BOOTP_BROADCAST); -@@ -3620,7 +3740,8 @@ - client -> packet.hops = 0; - client -> packet.xid = client -> xid; - client -> packet.secs = 0; /* Filled in by send_request. */ -- if (can_receive_unicast_unconfigured (client -> interface)) -+ if ((!(client->config-> bootp_broadcast_always)) -+ && can_receive_unicast_unconfigured (client->interface)) - client -> packet.flags = 0; - else - client -> packet.flags = htons (BOOTP_BROADCAST); -diff -urP a/common/bpf.c b/common/bpf.c ---- a/common/bpf.c 2022-09-28 08:39:15.000000000 -0600 -+++ b/common/bpf.c 2023-06-22 00:06:39.769025295 -0600 -@@ -116,7 +116,7 @@ - log_fatal ("Can't attach interface %s to bpf device %s: %m", - info -> name, filename); - -- get_hw_addr(info->name, &info->hw_address); -+ get_hw_addr(info); - - return sock; - } -@@ -237,11 +237,44 @@ - sizeof dhcp_bpf_relay_filter / sizeof (struct bpf_insn); - #endif - -+/* Packet filter program for DHCP over Infiniband. -+ * -+ * XXX -+ * Changes to the filter program may require changes to the constant offsets -+ * used in lpf_gen_filter_setup to patch the port in the BPF program! -+ * XXX -+ */ -+struct bpf_insn dhcp_ib_bpf_filter [] = { -+ /* Packet filter for Infiniband */ -+ /* Make sure it's a UDP packet... */ -+ BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 9), -+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6), -+ -+ /* Make sure this isn't a fragment... */ -+ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 6), -+ BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0), -+ -+ /* Get the IP header length... */ -+ BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 0), -+ -+ /* Make sure it's to the right port... */ -+ BPF_STMT(BPF_LD + BPF_H + BPF_IND, 2), -+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1), -+ -+ /* If we passed all the tests, ask for the whole packet. */ -+ BPF_STMT(BPF_RET + BPF_K, (u_int)-1), -+ -+ /* Otherwise, drop it. */ -+ BPF_STMT(BPF_RET + BPF_K, 0), -+}; -+ - #if defined (DEC_FDDI) - struct bpf_insn *bpf_fddi_filter = NULL; - #endif - - int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn); -+int dhcp_ib_bpf_filter_len = sizeof dhcp_ib_bpf_filter / sizeof (struct bpf_insn); -+ - #if defined (HAVE_TR_SUPPORT) - struct bpf_insn dhcp_bpf_tr_filter [] = { - /* accept all token ring packets due to variable length header */ -@@ -600,7 +633,9 @@ - - #if defined(USE_BPF_RECEIVE) || defined(USE_BPF_HWADDR) - void --get_hw_addr(const char *name, struct hardware *hw) { -+get_hw_addr(struct interface_info *info) { -+ struct hardware *hw = &info->hw_address; -+ const char *name = info->name; - struct ifaddrs *ifa; - struct ifaddrs *p; - struct sockaddr_dl *sa; -diff -urP a/common/conflex.c b/common/conflex.c ---- a/common/conflex.c 2022-09-28 08:39:15.000000000 -0600 -+++ b/common/conflex.c 2023-06-22 00:07:48.650031050 -0600 -@@ -832,6 +832,8 @@ - if (!strcasecmp(atom+1, "ig-endian")) { - return TOKEN_BIG_ENDIAN; - } -+ if (!strcasecmp (atom + 1, "ootp-broadcast-always")) -+ return BOOTP_BROADCAST_ALWAYS; - break; - case 'c': - if (!strcasecmp(atom + 1, "ase")) -diff -urP a/common/discover.c b/common/discover.c ---- a/common/discover.c 2022-09-28 08:39:15.000000000 -0600 -+++ b/common/discover.c 2023-06-22 00:06:39.770025295 -0600 -@@ -899,7 +899,7 @@ - if_register_send(tmp); - } else { - /* get_hw_addr() was called by register. */ -- get_hw_addr(tmp->name, &tmp->hw_address); -+ get_hw_addr(tmp); - } - break; - #ifdef DHCPv6 -@@ -912,7 +912,7 @@ - so now we have to call it explicitly - to not leave the hardware address unknown - (some code expects it cannot be. */ -- get_hw_addr(tmp->name, &tmp->hw_address); -+ get_hw_addr(tmp); - } else { - if_register_linklocal6(tmp); - } -diff -urP a/common/dlpi.c b/common/dlpi.c ---- a/common/dlpi.c 2022-09-28 08:39:15.000000000 -0600 -+++ b/common/dlpi.c 2023-06-22 00:06:39.770025295 -0600 -@@ -1343,7 +1343,9 @@ - #endif /* USE_DLPI_SEND */ - - void --get_hw_addr(const char *name, struct hardware *hw) { -+get_hw_addr(struct interface_info *info) { -+ struct hardware *hw = &info->hw_address; -+ const char *name = info->name; - int sock, unit; - long buf[DLPI_MAXDLBUF]; - union DL_primitives *dlp; -diff -urP a/common/lpf.c b/common/lpf.c ---- a/common/lpf.c 2022-09-28 08:39:15.000000000 -0600 -+++ b/common/lpf.c 2023-06-22 00:06:39.769025295 -0600 -@@ -45,6 +45,17 @@ - #include <sys/ioctl.h> - #include <sys/socket.h> - #include <net/if.h> -+#include <ifaddrs.h> -+ -+/* Default broadcast address for IPoIB */ -+static unsigned char default_ib_bcast_addr[20] = { -+ 0x00, 0xff, 0xff, 0xff, -+ 0xff, 0x12, 0x40, 0x1b, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+}; -+ - #endif - - #if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE) -@@ -78,10 +89,21 @@ - struct sockaddr common; - } sa; - struct ifreq ifr; -+ int type; -+ int protocol; - - /* Make an LPF socket. */ -- if ((sock = socket(PF_PACKET, SOCK_RAW, -- htons((short)ETH_P_ALL))) < 0) { -+ get_hw_addr(info); -+ -+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) { -+ type = SOCK_DGRAM; -+ protocol = ETHERTYPE_IP; -+ } else { -+ type = SOCK_RAW; -+ protocol = ETH_P_ALL; -+ } -+ -+ if ((sock = socket(PF_PACKET, type, htons((short)protocol))) < 0) { - if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT || - errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT || - errno == EAFNOSUPPORT || errno == EINVAL) { -@@ -104,6 +126,7 @@ - /* Bind to the interface name */ - memset (&sa, 0, sizeof sa); - sa.ll.sll_family = AF_PACKET; -+ sa.ll.sll_protocol = htons(protocol); - sa.ll.sll_ifindex = ifr.ifr_ifindex; - if (bind (sock, &sa.common, sizeof sa)) { - if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT || -@@ -120,8 +143,6 @@ - - } - -- get_hw_addr(info->name, &info->hw_address); -- - return sock; - } - #endif /* USE_LPF_SEND || USE_LPF_RECEIVE */ -@@ -176,6 +197,8 @@ - in bpf includes... */ - extern struct sock_filter dhcp_bpf_filter []; - extern int dhcp_bpf_filter_len; -+extern struct sock_filter dhcp_ib_bpf_filter []; -+extern int dhcp_ib_bpf_filter_len; - - #if defined(RELAY_PORT) - extern struct sock_filter dhcp_bpf_relay_filter []; -@@ -197,16 +220,14 @@ - info -> rfdesc = if_register_lpf (info); - - #ifdef PACKET_AUXDATA -- { -- int val = 1; -- -- if (setsockopt(info->rfdesc, SOL_PACKET, PACKET_AUXDATA, -- &val, sizeof(val)) < 0) { -- if (errno != ENOPROTOOPT) { -- log_fatal ("Failed to set auxiliary packet data: %m"); -+ if (info->hw_address.hbuf[0] != HTYPE_INFINIBAND) { -+ int val = 1; -+ if (setsockopt (info -> rfdesc, SOL_PACKET, PACKET_AUXDATA, -+ &val, sizeof val) < 0) { -+ if (errno != ENOPROTOOPT) -+ log_fatal ("Failed to set auxiliary packet data: %m"); - } - } -- } - #endif - - -@@ -253,26 +274,40 @@ - - memset(&p, 0, sizeof(p)); - -- /* Set up the bpf filter program structure. This is defined in -- bpf.c */ -- p.len = dhcp_bpf_filter_len; -- p.filter = dhcp_bpf_filter; -- -- /* Patch the server port into the LPF program... -- XXX changes to filter program may require changes -- to the insn number(s) used below! XXX */ -+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) { -+ /* Set up the bpf filter program structure. */ -+ p.len = dhcp_ib_bpf_filter_len; -+ p.filter = dhcp_ib_bpf_filter; -+ -+ /* Patch the server port into the LPF program... -+ XXX -+ changes to filter program may require changes -+ to the insn number(s) used below! -+ XXX */ -+ dhcp_ib_bpf_filter[6].k = ntohs ((short)local_port); -+ } else { -+ /* Set up the bpf filter program structure. -+ This is defined in bpf.c */ -+ p.len = dhcp_bpf_filter_len; -+ p.filter = dhcp_bpf_filter; -+ -+ /* Patch the server port into the LPF program... -+ XXX changes to filter program may require changes -+ to the insn number(s) used below! XXX */ - #if defined(RELAY_PORT) -- if (relay_port) { -- /* -- * If user defined relay UDP port, we need to filter -- * also on the user UDP port. -- */ -- p.len = dhcp_bpf_relay_filter_len; -- p.filter = dhcp_bpf_relay_filter; -+ if (relay_port) { -+ /* -+ * If user defined relay UDP port, we need to filter -+ * also on the user UDP port. -+ */ -+ p.len = dhcp_bpf_relay_filter_len; -+ p.filter = dhcp_bpf_relay_filter; - -- dhcp_bpf_relay_filter [10].k = ntohs (relay_port); -- } -+ dhcp_bpf_relay_filter [10].k = ntohs (relay_port); -+ } - #endif -+ dhcp_bpf_filter [8].k = ntohs ((short)local_port); -+ } - dhcp_bpf_filter [8].k = ntohs (local_port); - - if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p, -@@ -330,6 +365,54 @@ - #endif /* USE_LPF_RECEIVE */ - - #ifdef USE_LPF_SEND -+ssize_t send_packet_ib(interface, packet, raw, len, from, to, hto) -+ struct interface_info *interface; -+ struct packet *packet; -+ struct dhcp_packet *raw; -+ size_t len; -+ struct in_addr from; -+ struct sockaddr_in *to; -+ struct hardware *hto; -+{ -+ unsigned ibufp = 0; -+ double ih [1536 / sizeof (double)]; -+ unsigned char *buf = (unsigned char *)ih; -+ ssize_t result; -+ -+ union sockunion { -+ struct sockaddr sa; -+ struct sockaddr_ll sll; -+ struct sockaddr_storage ss; -+ } su; -+ -+ assemble_udp_ip_header (interface, buf, &ibufp, from.s_addr, -+ to->sin_addr.s_addr, to->sin_port, -+ (unsigned char *)raw, len); -+ memcpy (buf + ibufp, raw, len); -+ -+ memset(&su, 0, sizeof(su)); -+ su.sll.sll_family = AF_PACKET; -+ su.sll.sll_protocol = htons(ETHERTYPE_IP); -+ -+ if (!(su.sll.sll_ifindex = if_nametoindex(interface->name))) { -+ errno = ENOENT; -+ log_error ("send_packet_ib: %m - failed to get if index"); -+ return -1; -+ } -+ -+ su.sll.sll_hatype = htons(HTYPE_INFINIBAND); -+ su.sll.sll_halen = sizeof(interface->bcast_addr); -+ memcpy(&su.sll.sll_addr, interface->bcast_addr, 20); -+ -+ result = sendto(interface->wfdesc, buf, ibufp + len, 0, -+ &su.sa, sizeof(su)); -+ -+ if (result < 0) -+ log_error ("send_packet_ib: %m"); -+ -+ return result; -+} -+ - ssize_t send_packet (interface, packet, raw, len, from, to, hto) - struct interface_info *interface; - struct packet *packet; -@@ -350,6 +433,11 @@ - return send_fallback (interface, packet, raw, - len, from, to, hto); - -+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) { -+ return send_packet_ib(interface, packet, raw, len, from, -+ to, hto); -+ } -+ - if (hto == NULL && interface->anycast_mac_addr.hlen) - hto = &interface->anycast_mac_addr; - -@@ -370,6 +458,42 @@ - #endif /* USE_LPF_SEND */ - - #ifdef USE_LPF_RECEIVE -+ssize_t receive_packet_ib (interface, buf, len, from, hfrom) -+ struct interface_info *interface; -+ unsigned char *buf; -+ size_t len; -+ struct sockaddr_in *from; -+ struct hardware *hfrom; -+{ -+ int length = 0; -+ int offset = 0; -+ unsigned char ibuf [1536]; -+ unsigned bufix = 0; -+ unsigned paylen; -+ -+ length = read(interface->rfdesc, ibuf, sizeof(ibuf)); -+ -+ if (length <= 0) -+ return length; -+ -+ offset = decode_udp_ip_header(interface, ibuf, bufix, from, -+ (unsigned)length, &paylen, 0); -+ -+ if (offset < 0) -+ return 0; -+ -+ bufix += offset; -+ length -= offset; -+ -+ if (length < paylen) -+ log_fatal("Internal inconsistency at %s:%d.", MDL); -+ -+ /* Copy out the data in the packet... */ -+ memcpy(buf, &ibuf[bufix], paylen); -+ -+ return (ssize_t)paylen; -+} -+ - ssize_t receive_packet (interface, buf, len, from, hfrom) - struct interface_info *interface; - unsigned char *buf; -@@ -408,6 +532,10 @@ - }; - #endif /* PACKET_AUXDATA */ - -+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) { -+ return receive_packet_ib(interface, buf, len, from, hfrom); -+ } -+ - length = recvmsg (interface->rfdesc, &msg, 0); - if (length <= 0) - return length; -@@ -521,11 +649,33 @@ - #endif - - #if defined (USE_LPF_RECEIVE) || defined (USE_LPF_HWADDR) --void --get_hw_addr(const char *name, struct hardware *hw) { -+struct sockaddr_ll * -+get_ll (struct ifaddrs *ifaddrs, struct ifaddrs **ifa, char *name) -+{ -+ for (*ifa = ifaddrs; *ifa != NULL; *ifa = (*ifa)->ifa_next) { -+ if ((*ifa)->ifa_addr == NULL) -+ continue; -+ -+ if ((*ifa)->ifa_addr->sa_family != AF_PACKET) -+ continue; -+ -+ if ((*ifa)->ifa_flags & IFF_LOOPBACK) -+ continue; -+ -+ if (strcmp((*ifa)->ifa_name, name) == 0) -+ return (struct sockaddr_ll *)(void *)(*ifa)->ifa_addr; -+ } -+ *ifa = NULL; -+ return NULL; -+} -+ -+struct sockaddr_ll * -+ioctl_get_ll(char *name) -+{ - int sock; - struct ifreq tmp; -- struct sockaddr *sa; -+ struct sockaddr *sa = NULL; -+ struct sockaddr_ll *sll = NULL; - - if (strlen(name) >= sizeof(tmp.ifr_name)) { - log_fatal("Device name too long: \"%s\"", name); -@@ -542,13 +692,59 @@ - log_fatal("Error getting hardware address for \"%s\": %m", - name); - } -+ close(sock); - - sa = &tmp.ifr_hwaddr; -- switch (sa->sa_family) { -+ // needs to be freed outside this function -+ sll = dmalloc (sizeof (struct sockaddr_ll), MDL); -+ if (!sll) -+ log_fatal("Unable to allocate memory for link layer address"); -+ memcpy(&sll->sll_hatype, &sa->sa_family, sizeof (sll->sll_hatype)); -+ memcpy(sll->sll_addr, sa->sa_data, sizeof (sll->sll_addr)); -+ switch (sll->sll_hatype) { -+ case ARPHRD_INFINIBAND: -+ /* ioctl limits hardware addresses to 8 bytes */ -+ sll->sll_halen = 8; -+ break; -+ default: -+ break; -+ } -+ return sll; -+} -+ -+void -+get_hw_addr(struct interface_info *info) -+{ -+ struct hardware *hw = &info->hw_address; -+ char *name = info->name; -+ struct ifaddrs *ifaddrs = NULL; -+ struct ifaddrs *ifa = NULL; -+ struct sockaddr_ll *sll = NULL; -+ int sll_allocated = 0; -+ char *dup = NULL; -+ char *colon = NULL; -+ -+ if (getifaddrs(&ifaddrs) == -1) -+ log_fatal("Failed to get interfaces"); -+ -+ if ((sll = get_ll(ifaddrs, &ifa, name)) == NULL) { -+ /* -+ * We were unable to get link-layer address for name. -+ * Fall back to ioctl(SIOCGIFHWADDR). -+ */ -+ sll = ioctl_get_ll(name); -+ if (sll != NULL) -+ sll_allocated = 1; -+ else -+ // shouldn't happen -+ log_fatal("Unexpected internal error"); -+ } -+ -+ switch (sll->sll_hatype) { - case ARPHRD_ETHER: - hw->hlen = 7; - hw->hbuf[0] = HTYPE_ETHER; -- memcpy(&hw->hbuf[1], sa->sa_data, 6); -+ memcpy(&hw->hbuf[1], sll->sll_addr, 6); - break; - case ARPHRD_IEEE802: - #ifdef ARPHRD_IEEE802_TR -@@ -556,18 +752,51 @@ - #endif /* ARPHRD_IEEE802_TR */ - hw->hlen = 7; - hw->hbuf[0] = HTYPE_IEEE802; -- memcpy(&hw->hbuf[1], sa->sa_data, 6); -+ memcpy(&hw->hbuf[1], sll->sll_addr, 6); - break; - case ARPHRD_FDDI: - hw->hlen = 7; - hw->hbuf[0] = HTYPE_FDDI; -- memcpy(&hw->hbuf[1], sa->sa_data, 6); -+ memcpy(&hw->hbuf[1], sll->sll_addr, 6); -+ break; -+ case ARPHRD_INFINIBAND: -+ dup = strdup(name); -+ /* Aliased infiniband interface is special case where -+ * neither get_ll() nor ioctl_get_ll() get's correct hw -+ * address, so we have to truncate the :0 and run -+ * get_ll() again for the rest. -+ */ -+ if ((colon = strchr(dup, ':')) != NULL) { -+ *colon = '\0'; -+ if ((sll = get_ll(ifaddrs, &ifa, dup)) == NULL) -+ log_fatal("Error getting hardware address for \"%s\": %m", name); -+ } -+ free (dup); -+ /* For Infiniband, save the broadcast address and store -+ * the port GUID into the hardware address. -+ */ -+ if (ifa && (ifa->ifa_flags & IFF_BROADCAST)) { -+ struct sockaddr_ll *bll; -+ -+ bll = (struct sockaddr_ll *)ifa->ifa_broadaddr; -+ memcpy(&info->bcast_addr, bll->sll_addr, 20); -+ } else { -+ memcpy(&info->bcast_addr, default_ib_bcast_addr, -+ 20); -+ } -+ -+ hw->hlen = 1; -+ hw->hbuf[0] = HTYPE_INFINIBAND; -+ memcpy(&hw->hbuf[1], &sll->sll_addr[sll->sll_halen - 8], 8); - break; - default: -- log_fatal("Unsupported device type %ld for \"%s\"", -- (long int)sa->sa_family, name); -+ freeifaddrs(ifaddrs); -+ log_fatal("Unsupported device type %hu for \"%s\"", -+ sll->sll_hatype, name); - } - -- close(sock); -+ if (sll_allocated) -+ dfree(sll, MDL); -+ freeifaddrs(ifaddrs); - } - #endif -diff -urP a/common/socket.c b/common/socket.c ---- a/common/socket.c 2023-06-21 23:44:22.498212253 -0600 -+++ b/common/socket.c 2023-06-22 00:06:39.769025295 -0600 -@@ -358,7 +358,7 @@ - info->wfdesc = if_register_socket(info, AF_INET, 0, NULL); - /* If this is a normal IPv4 address, get the hardware address. */ - if (strcmp(info->name, "fallback") != 0) -- get_hw_addr(info->name, &info->hw_address); -+ get_hw_addr(info); - #if defined (USE_SOCKET_FALLBACK) - /* Fallback only registers for send, but may need to receive as - well. */ -@@ -421,7 +421,7 @@ - #endif /* IP_PKTINFO... */ - /* If this is a normal IPv4 address, get the hardware address. */ - if (strcmp(info->name, "fallback") != 0) -- get_hw_addr(info->name, &info->hw_address); -+ get_hw_addr(info); - - if (!quiet_interface_discovery) - log_info ("Listening on Socket/%s%s%s", -@@ -577,7 +577,7 @@ - if (req_multi) - if_register_multicast(info); - -- get_hw_addr(info->name, &info->hw_address); -+ get_hw_addr(info); - - if (!quiet_interface_discovery) { - if (info->shared_network != NULL) { -@@ -633,7 +633,7 @@ - info->rfdesc = sock; - info->wfdesc = sock; - -- get_hw_addr(info->name, &info->hw_address); -+ get_hw_addr(info); - - if (!quiet_interface_discovery) { - if (info->shared_network != NULL) { -@@ -1246,7 +1246,9 @@ - #if defined(sun) && defined(USE_V4_PKTINFO) - /* This code assumes the existence of SIOCGLIFHWADDR */ - void --get_hw_addr(const char *name, struct hardware *hw) { -+get_hw_addr(struct interface_info *info) { -+ struct hardware *hw = &info->hw_address; -+ const char *name = info->name; - struct sockaddr_dl *dladdrp; - int sock, i; - struct lifreq lifr; -diff -urP a/includes/dhcpd.h b/includes/dhcpd.h ---- a/includes/dhcpd.h 2022-09-28 08:39:15.000000000 -0600 -+++ b/includes/dhcpd.h 2023-06-22 00:07:48.661031051 -0600 -@@ -1284,6 +1284,9 @@ - - int lease_id_format; /* format for IDs in lease file, - TOKEN_OCTAL or TOKEN_HEX */ -+ -+ int bootp_broadcast_always; /* If nonzero, always set the BOOTP_BROADCAST -+ flag in requests */ - }; - - /* Per-interface state used in the dhcp client... */ -@@ -1377,6 +1380,7 @@ - struct shared_network *shared_network; - /* Networks connected to this interface. */ - struct hardware hw_address; /* Its physical address. */ -+ u_int8_t bcast_addr[20]; /* Infiniband broadcast address */ - struct in_addr *addresses; /* Addresses associated with this - * interface. - */ -@@ -2646,7 +2650,7 @@ - #endif - const char *print_time(TIME); - --void get_hw_addr(const char *name, struct hardware *hw); -+void get_hw_addr(struct interface_info *info); - char *buf_to_hex (const unsigned char *s, unsigned len, - const char *file, int line); - char *format_lease_id(const unsigned char *s, unsigned len, int format, -diff -urP a/includes/dhctoken.h b/includes/dhctoken.h ---- a/includes/dhctoken.h 2022-09-28 08:39:15.000000000 -0600 -+++ b/includes/dhctoken.h 2023-06-22 00:07:48.662031051 -0600 -@@ -377,7 +377,8 @@ - TOKEN_HEX = 677, - TOKEN_OCTAL = 678, - KEY_ALGORITHM = 679, -- DISCONNECT = 680 -+ DISCONNECT = 680, -+ BOOTP_BROADCAST_ALWAYS = 681 - }; - - #define is_identifier(x) ((x) >= FIRST_TOKEN && \ |