Projects
Eulaceura:Factory
dhcp
_service:obs_scm:bugfix-reduce-getifaddr-calls....
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:bugfix-reduce-getifaddr-calls.patch of Package dhcp
From 722051d384b940091ed6f1acf60d22fdb65efde6 Mon Sep 17 00:00:00 2001 From: LuZhang<zhanglu37@huawei.com> Date: Thu, 19 Sep 2019 16:05:23 +0800 Subject: [PATCH] Module: DHCP reason: reducing getifaddrs calls and improving running performance Signed-off-by: LuZhang<zhanglu37@huawei.com> --- common/discover.c | 5 +- common/lpf.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++ includes/dhcpd.h | 5 ++ 3 files changed, 122 insertions(+), 1 deletion(-) diff --git a/common/discover.c b/common/discover.c index 6860645..26be5de 100644 --- a/common/discover.c +++ b/common/discover.c @@ -588,9 +588,12 @@ discover_interfaces(int state) { #endif static int setup_fallback = 0; + struct ifaddrs *ifaddrs_start = NULL; if (!begin_iface_scan(&ifaces)) { log_fatal("Can't get list of interfaces."); + } else { + ifaddrs_start = ifaces.head; } /* If we already have a list of interfaces, and we're running as @@ -651,7 +654,7 @@ discover_interfaces(int state) { tmp = interfaces; /* XXX */ } if (tmp != NULL) - try_hw_addr(tmp); + try_hw_addr2(tmp, ifaddrs_start); if (dhcp_interface_discovery_hook) { (*dhcp_interface_discovery_hook)(tmp); index 9ec8a31..823ba6b 100644 --- a/common/lpf.c +++ b/common/lpf.c @@ -697,6 +697,119 @@ ioctl_get_ll(char *name) return sll; } +isc_result_t +get_hw_addr3(struct interface_info *info, struct ifaddrs *ifaddrs_start) +{ + struct hardware *hw = &info->hw_address; + char *name = info->name; + struct ifaddrs *ifaddrs = ifaddrs_start; + struct ifaddrs *ifa = NULL; + struct sockaddr_ll *sll = NULL; + int sll_allocated = 0; + char *dup = NULL; + char *colon = NULL; + isc_result_t result = ISC_R_SUCCESS; + + if (ifaddrs == NULL) + 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], sll->sll_addr, 6); + break; + case ARPHRD_IEEE802: +#ifdef ARPHRD_IEEE802_TR + case ARPHRD_IEEE802_TR: +#endif /* ARPHRD_IEEE802_TR */ + hw->hlen = 7; + hw->hbuf[0] = HTYPE_IEEE802; + memcpy(&hw->hbuf[1], sll->sll_addr, 6); + break; + case ARPHRD_FDDI: + hw->hlen = 7; + hw->hbuf[0] = HTYPE_FDDI; + 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 = HARDWARE_ADDR_LEN_IOCTL + 1; + hw->hbuf[0] = HTYPE_INFINIBAND; + memcpy(&hw->hbuf[1], + &sll->sll_addr[sll->sll_halen - HARDWARE_ADDR_LEN_IOCTL], + HARDWARE_ADDR_LEN_IOCTL); + break; +#if defined(ARPHRD_PPP) + case ARPHRD_PPP: + if (local_family != AF_INET6) + log_fatal("local_family != AF_INET6 for \"%s\"", + name); + hw->hlen = 0; + hw->hbuf[0] = HTYPE_RESERVED; + /* 0xdeadbeef should never occur on the wire, + * and is a signature that something went wrong. + */ + hw->hbuf[1] = 0xde; + hw->hbuf[2] = 0xad; + hw->hbuf[3] = 0xbe; + hw->hbuf[4] = 0xef; + break; +#endif + default: + log_error("Unsupported device type %hu for \"%s\"", + sll->sll_hatype, name); + result = ISC_R_NOTFOUND; + + } + + if (sll_allocated) + dfree(sll, MDL); + //freeifaddrs(ifaddrs); + return result; +} + +void try_hw_addr2(struct interface_info *info, struct ifaddrs *ifaddrs_start){ + get_hw_addr3(info, ifaddrs_start); +} + // define ? void try_hw_addr(struct interface_info *info){ get_hw_addr2(info); diff --git a/includes/dhcpd.h b/includes/dhcpd.h index 40b5bdc..c9260e7 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h @@ -29,6 +29,7 @@ /*! \file includes/dhcpd.h */ #include "config.h" +#include <ifaddrs.h> #ifndef __CYGWIN32__ #include <sys/types.h> @@ -2595,6 +2596,10 @@ const char *print_time(TIME); void get_hw_addr(struct interface_info *info); void try_hw_addr(struct interface_info *info); + +void try_hw_addr2(struct interface_info *info, struct ifaddrs *ifaddrs_start); +isc_result_t get_hw_addr3(struct interface_info *info, struct ifaddrs *ifaddrs_start); + isc_result_t get_hw_addr2(struct interface_info *info); char *buf_to_hex (const unsigned char *s, unsigned len, const char *file, int line); -- 2.19.1
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2