From cd552e5d9933d6d2a28a8096177e7c8d2e06d7f1 Mon Sep 17 00:00:00 2001 From: Jiri Popelka Date: Mon, 23 Jul 2012 13:39:43 +0200 Subject: [PATCH] ib.patch: added fall-back method ioctl_get_ll() (#626514-c#63, #840601). --- dhcp-4.2.2-gpxe-cid.patch | 2 +- dhcp-4.2.4-lpf-ib.patch | 108 +++++++++++++++++++------------------- dhcp.spec | 6 ++- 3 files changed, 61 insertions(+), 55 deletions(-) diff --git a/dhcp-4.2.2-gpxe-cid.patch b/dhcp-4.2.2-gpxe-cid.patch index 595511b..d9dea5c 100644 --- a/dhcp-4.2.2-gpxe-cid.patch +++ b/dhcp-4.2.2-gpxe-cid.patch @@ -74,7 +74,7 @@ diff -up dhcp-4.2.2/common/lpf.c.gpxe-cid dhcp-4.2.2/common/lpf.c --- dhcp-4.2.2/common/lpf.c.gpxe-cid 2011-09-16 18:23:20.183453996 +0200 +++ dhcp-4.2.2/common/lpf.c 2011-09-16 18:25:28.235804421 +0200 @@ -591,6 +591,37 @@ void maybe_setup_fallback () - return NULL; + return sll; } +static unsigned char * get_ib_hw_addr(char * name) diff --git a/dhcp-4.2.4-lpf-ib.patch b/dhcp-4.2.4-lpf-ib.patch index 0692b59..fa54c9e 100644 --- a/dhcp-4.2.4-lpf-ib.patch +++ b/dhcp-4.2.4-lpf-ib.patch @@ -1,6 +1,6 @@ diff -up dhcp-4.2.4/client/dhclient.c.lpf-ib dhcp-4.2.4/client/dhclient.c ---- dhcp-4.2.4/client/dhclient.c.lpf-ib 2012-07-18 16:41:17.958560314 +0200 -+++ dhcp-4.2.4/client/dhclient.c 2012-07-18 16:41:17.971560135 +0200 +--- dhcp-4.2.4/client/dhclient.c.lpf-ib 2012-07-18 21:08:48.100835005 +0200 ++++ dhcp-4.2.4/client/dhclient.c 2012-07-18 21:08:48.111834856 +0200 @@ -113,6 +113,8 @@ static int check_domain_name_list(const static int check_option_values(struct universe *universe, unsigned int opt, const char *ptr, size_t len); @@ -56,8 +56,8 @@ diff -up dhcp-4.2.4/client/dhclient.c.lpf-ib dhcp-4.2.4/client/dhclient.c * * Each routine is called from the dhclient_state_machine() in one of diff -up dhcp-4.2.4/common/bpf.c.lpf-ib dhcp-4.2.4/common/bpf.c ---- dhcp-4.2.4/common/bpf.c.lpf-ib 2012-07-18 16:41:17.959560300 +0200 -+++ dhcp-4.2.4/common/bpf.c 2012-07-18 16:41:17.972560121 +0200 +--- dhcp-4.2.4/common/bpf.c.lpf-ib 2012-07-18 21:08:48.101834991 +0200 ++++ dhcp-4.2.4/common/bpf.c 2012-07-18 21:08:48.111834856 +0200 @@ -198,11 +198,44 @@ struct bpf_insn dhcp_bpf_filter [] = { BPF_STMT(BPF_RET+BPF_K, 0), }; @@ -104,8 +104,8 @@ diff -up dhcp-4.2.4/common/bpf.c.lpf-ib dhcp-4.2.4/common/bpf.c struct bpf_insn dhcp_bpf_tr_filter [] = { /* accept all token ring packets due to variable length header */ diff -up dhcp-4.2.4/common/lpf.c.lpf-ib dhcp-4.2.4/common/lpf.c ---- dhcp-4.2.4/common/lpf.c.lpf-ib 2012-07-18 16:41:17.960560286 +0200 -+++ dhcp-4.2.4/common/lpf.c 2012-07-18 16:41:35.004325607 +0200 +--- dhcp-4.2.4/common/lpf.c.lpf-ib 2012-07-18 21:08:48.101834991 +0200 ++++ dhcp-4.2.4/common/lpf.c 2012-07-18 21:10:47.367210799 +0200 @@ -42,6 +42,7 @@ #include "includes/netinet/udp.h" #include "includes/netinet/if_ether.h" @@ -358,45 +358,61 @@ diff -up dhcp-4.2.4/common/lpf.c.lpf-ib dhcp-4.2.4/common/lpf.c length = recvmsg (interface -> rfdesc, &msg, 0); if (length <= 0) return length; -@@ -461,34 +591,63 @@ void maybe_setup_fallback () +@@ -461,11 +591,32 @@ void maybe_setup_fallback () } } -void -get_hw_addr(const char *name, struct hardware *hw) { -- int sock; -- struct ifreq tmp; -- struct sockaddr *sa; +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 (strlen(name) >= sizeof(tmp.ifr_name)) { -- log_fatal("Device name too long: \"%s\"", name); -- } ++ + if ((*ifa)->ifa_addr->sa_family != AF_PACKET) + continue; + + if ((*ifa)->ifa_flags & IFF_LOOPBACK) + continue; - -- sock = socket(AF_INET, SOCK_DGRAM, 0); -- if (sock < 0) { -- log_fatal("Can't create socket for \"%s\": %m", name); ++ + if (strcmp((*ifa)->ifa_name, name) == 0) -+ return (struct sockaddr_ll **)(*ifa)->ifa_addr; - } ++ return (struct sockaddr_ll *)(*ifa)->ifa_addr; ++ } + 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; -- memset(&tmp, 0, sizeof(tmp)); -- strcpy(tmp.ifr_name, name); -- if (ioctl(sock, SIOCGIFHWADDR, &tmp) < 0) { + if (strlen(name) >= sizeof(tmp.ifr_name)) { + log_fatal("Device name too long: \"%s\"", name); +@@ -479,16 +630,44 @@ get_hw_addr(const char *name, struct har + memset(&tmp, 0, sizeof(tmp)); + strcpy(tmp.ifr_name, name); + if (ioctl(sock, SIOCGIFHWADDR, &tmp) < 0) { - log_fatal("Error getting hardware address for \"%s\": %m", -- name); ++ log_fatal("Error getting hardware address for \"%s\": %m", + name); + } + + sa = &tmp.ifr_hwaddr; +- switch (sa->sa_family) { ++ 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)); ++ return sll; ++} ++ +void +get_hw_addr(struct interface_info *info) +{ @@ -410,28 +426,13 @@ diff -up dhcp-4.2.4/common/lpf.c.lpf-ib dhcp-4.2.4/common/lpf.c + log_fatal("Failed to get interfaces"); + + if ((sll = get_ll(ifaddrs, &ifa, name)) == NULL) { -+ char *tmp = NULL; -+ char *real_name = strdup (name); + /* + * We were unable to get link-layer address for name. -+ * Reason could be RHBZ#840601. ++ * Fall back to ioctl(SIOCGIFHWADDR). + */ -+ if ((tmp = strrchr (real_name, ':')) != NULL) { -+ *tmp = '\0'; -+ log_debug("Failed to get HW address for %s. Seems to be an alias, trying %s instead.\n", name, real_name); -+ if ((sll = get_ll(ifaddrs, &ifa, real_name)) == NULL) { -+ freeifaddrs(ifaddrs); -+ log_fatal("Failed to get HW address for %s\n", name); -+ } -+ } else { -+ freeifaddrs(ifaddrs); -+ log_fatal("Failed to get HW address for %s\n", name); -+ } -+ free (real_name); - } - -- sa = &tmp.ifr_hwaddr; -- switch (sa->sa_family) { ++ sll = ioctl_get_ll(name); ++ } ++ + switch (sll->sll_hatype) { case ARPHRD_ETHER: hw->hlen = 7; @@ -441,7 +442,7 @@ diff -up dhcp-4.2.4/common/lpf.c.lpf-ib dhcp-4.2.4/common/lpf.c break; case ARPHRD_IEEE802: #ifdef ARPHRD_IEEE802_TR -@@ -496,18 +655,35 @@ get_hw_addr(const char *name, struct har +@@ -496,18 +675,35 @@ get_hw_addr(const char *name, struct har #endif /* ARPHRD_IEEE802_TR */ hw->hlen = 7; hw->hbuf[0] = HTYPE_IEEE802; @@ -476,19 +477,20 @@ diff -up dhcp-4.2.4/common/lpf.c.lpf-ib dhcp-4.2.4/common/lpf.c if (local_family != AF_INET6) - log_fatal("Unsupported device type %d for \"%s\"", - sa->sa_family, name); -+ log_fatal("Unsupported device type %ld for \"%s\"", -+ (long int)sll->sll_family, name); ++ log_fatal("local_family != AF_INET6 for \"%s\"", ++ name); hw->hlen = 0; hw->hbuf[0] = HTYPE_RESERVED; /* 0xdeadbeef should never occur on the wire, -@@ -520,10 +696,11 @@ get_hw_addr(const char *name, struct har +@@ -520,10 +716,11 @@ get_hw_addr(const char *name, struct har break; #endif default: -+ freeifaddrs(ifaddrs); - log_fatal("Unsupported device type %ld for \"%s\"", +- log_fatal("Unsupported device type %ld for \"%s\"", - (long int)sa->sa_family, name); -+ (long int)sll->sll_family, name); ++ freeifaddrs(ifaddrs); ++ log_fatal("Unsupported device type %h for \"%s\"", ++ sll->sll_hatype, name); } - close(sock); @@ -497,7 +499,7 @@ diff -up dhcp-4.2.4/common/lpf.c.lpf-ib dhcp-4.2.4/common/lpf.c #endif diff -up dhcp-4.2.4/common/socket.c.lpf-ib dhcp-4.2.4/common/socket.c --- dhcp-4.2.4/common/socket.c.lpf-ib 2012-03-09 12:28:11.000000000 +0100 -+++ dhcp-4.2.4/common/socket.c 2012-07-18 16:41:17.973560107 +0200 ++++ dhcp-4.2.4/common/socket.c 2012-07-18 21:08:48.112834843 +0200 @@ -325,7 +325,7 @@ void if_register_send (info) info->wfdesc = if_register_socket(info, AF_INET, 0); /* If this is a normal IPv4 address, get the hardware address. */ @@ -526,8 +528,8 @@ diff -up dhcp-4.2.4/common/socket.c.lpf-ib dhcp-4.2.4/common/socket.c if (!quiet_interface_discovery) { if (info->shared_network != NULL) { diff -up dhcp-4.2.4/includes/dhcpd.h.lpf-ib dhcp-4.2.4/includes/dhcpd.h ---- dhcp-4.2.4/includes/dhcpd.h.lpf-ib 2012-07-18 16:41:17.961560272 +0200 -+++ dhcp-4.2.4/includes/dhcpd.h 2012-07-18 16:41:17.975560079 +0200 +--- dhcp-4.2.4/includes/dhcpd.h.lpf-ib 2012-07-18 21:08:48.102834978 +0200 ++++ dhcp-4.2.4/includes/dhcpd.h 2012-07-18 21:08:48.114834815 +0200 @@ -1243,6 +1243,7 @@ struct interface_info { struct shared_network *shared_network; /* Networks connected to this interface. */ diff --git a/dhcp.spec b/dhcp.spec index f6cdeb9..b9b2f53 100644 --- a/dhcp.spec +++ b/dhcp.spec @@ -18,7 +18,7 @@ Summary: Dynamic host configuration protocol software Name: dhcp Version: 4.2.4 -Release: 5%{?dist} +Release: 6%{?dist} # NEVER CHANGE THE EPOCH on this package. The previous maintainer (prior to # dcantrell maintaining the package) made incorrect use of the epoch and # that's why it is at 12 now. It should have never been used, but it was. @@ -571,6 +571,10 @@ fi %changelog +* Mon Jul 23 2012 Jiri Popelka - 12:4.2.4-6 +- ib.patch: added fall-back method (using ioctl(SIOCGIFHWADDR)) when getting + of HW address with getifaddrs() fails (#626514-c#63, #840601). + * Mon Jul 23 2012 Tomas Hozza - 12:4.2.4-5 - Dhcpd does not correctly follow DhcpFailOverPeerDN (#838400)