From: Shawn Routhier Date: Thu, 16 Feb 2012 21:09:15 +0000 (+0000) Subject: Add support for Infiniband over sockets to the server and X-Git-Tag: v4_2_4b1~30 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=74ebd2043be6011094305e1b644e9d71aebde3c3;p=thirdparty%2Fdhcp.git Add support for Infiniband over sockets to the server and relay code. We've tested this on Solaris and hope to expand support for Infiniband in the future. This patch also corrects some issues we found in the socket code. [ISC-Bugs #24245] --- diff --git a/RELNOTES b/RELNOTES index 2ce2ea7f3..a2d73d8f0 100644 --- a/RELNOTES +++ b/RELNOTES @@ -73,7 +73,12 @@ work on other platforms. Please report any problems and suggested fixes to - Tidy up the receive calls and eliminate the need for found_pkt [ISC-Bugs #25066] - + +- Add support for Infiniband over sockets to the server and + relay code. We've tested this on Solaris and hope to expand + support for Infiniband in the future. This patch also corrects + some issues we found in the socket code. [ISC-Bugs #24245] + Changes since 4.2.2 - Fix the code that checks for an existing DDNS transaction to cancel diff --git a/common/conflex.c b/common/conflex.c index 9c9ed66ab..0ae5e696e 100644 --- a/common/conflex.c +++ b/common/conflex.c @@ -3,7 +3,7 @@ Lexical scanner for dhcpd config file... */ /* - * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2012 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any @@ -1043,6 +1043,8 @@ intern(char *atom, enum dhcp_token dfv) { return INCLUDE; if (!strcasecmp (atom + 1, "nteger")) return INTEGER; + if (!strcasecmp (atom + 1, "nfiniband")) + return TOKEN_INFINIBAND; if (!strcasecmp (atom + 1, "nfinite")) return INFINITE; if (!strcasecmp (atom + 1, "nfo")) diff --git a/common/packet.c b/common/packet.c index 42bca69c5..45e96e82c 100644 --- a/common/packet.c +++ b/common/packet.c @@ -3,7 +3,8 @@ Packet assembly code, originally contributed by Archie Cobbs. */ /* - * Copyright (c) 2004,2005,2007,2009 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2009,2012 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004,2005,2007 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any @@ -105,18 +106,25 @@ void assemble_hw_header (interface, buf, bufix, to) unsigned *bufix; struct hardware *to; { -#if defined (HAVE_TR_SUPPORT) - if (interface -> hw_address.hbuf [0] == HTYPE_IEEE802) - assemble_tr_header (interface, buf, bufix, to); - else + switch (interface->hw_address.hbuf[0]) { +#if defined(HAVE_TR_SUPPORT) + case HTYPE_IEEE802: + assemble_tr_header(interface, buf, bufix, to); + break; #endif #if defined (DEC_FDDI) - if (interface -> hw_address.hbuf [0] == HTYPE_FDDI) - assemble_fddi_header (interface, buf, bufix, to); - else + case HTYPE_FDDI: + assemble_fddi_header(interface, buf, bufix, to); + break; #endif - assemble_ethernet_header (interface, buf, bufix, to); - + case HTYPE_INFINIBAND: + log_error("Attempt to assemble hw header for infiniband"); + break; + case HTYPE_ETHER: + default: + assemble_ethernet_header(interface, buf, bufix, to); + break; + } } /* UDP header and IP header assembled together for convenience. */ @@ -184,7 +192,9 @@ void assemble_udp_ip_header (interface, buf, bufix, #ifdef PACKET_DECODING /* Decode a hardware header... */ -/* XXX currently only supports ethernet; doesn't check for other types. */ +/* Support for ethernet, TR and FDDI + * Doesn't support infiniband yet as the supported oses shouldn't get here + */ ssize_t decode_hw_header (interface, buf, bufix, from) struct interface_info *interface; @@ -192,17 +202,22 @@ ssize_t decode_hw_header (interface, buf, bufix, from) unsigned bufix; struct hardware *from; { + switch(interface->hw_address.hbuf[0]) { #if defined (HAVE_TR_SUPPORT) - if (interface -> hw_address.hbuf [0] == HTYPE_IEEE802) - return decode_tr_header (interface, buf, bufix, from); - else + case HTYPE_IEEE802: + return (decode_tr_header(interface, buf, bufix, from)); #endif #if defined (DEC_FDDI) - if (interface -> hw_address.hbuf [0] == HTYPE_FDDI) - return decode_fddi_header (interface, buf, bufix, from); - else + case HTYPE_FDDI: + return (decode_fddi_header(interface, buf, bufix, from)); #endif - return decode_ethernet_header (interface, buf, bufix, from); + case HTYPE_INFINIBAND: + log_error("Attempt to decode hw header for infiniband"); + return (0); + case HTYPE_ETHER: + default: + return (decode_ethernet_header(interface, buf, bufix, from)); + } } /* UDP header and IP header decoded together for convenience. */ diff --git a/common/parse.c b/common/parse.c index 61488c159..0d3e7c601 100644 --- a/common/parse.c +++ b/common/parse.c @@ -3,7 +3,7 @@ Common parser code for dhcpd and dhclient. */ /* - * Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2012 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any @@ -569,7 +569,9 @@ parse_ip_addr_with_subnet(cfile, match) /* * hardware-parameter :== HARDWARE hardware-type colon-separated-hex-list SEMI - * hardware-type :== ETHERNET | TOKEN_RING | TOKEN_FDDI + * hardware-type :== ETHERNET | TOKEN_RING | TOKEN_FDDI | INFINIBAND + * Note that INFINIBAND may not be useful for some items, such as classification + * as the hardware address won't always be available. */ void parse_hardware_param (cfile, hardware) @@ -581,24 +583,27 @@ void parse_hardware_param (cfile, hardware) unsigned hlen; unsigned char *t; - token = next_token (&val, (unsigned *)0, cfile); + token = next_token(&val, NULL, cfile); switch (token) { case ETHERNET: - hardware -> hbuf [0] = HTYPE_ETHER; + hardware->hbuf[0] = HTYPE_ETHER; break; case TOKEN_RING: - hardware -> hbuf [0] = HTYPE_IEEE802; + hardware->hbuf[0] = HTYPE_IEEE802; break; case TOKEN_FDDI: - hardware -> hbuf [0] = HTYPE_FDDI; + hardware->hbuf[0] = HTYPE_FDDI; + break; + case TOKEN_INFINIBAND: + hardware->hbuf[0] = HTYPE_INFINIBAND; break; default: - if (!strncmp (val, "unknown-", 8)) { - hardware -> hbuf [0] = atoi (&val [8]); + if (!strncmp(val, "unknown-", 8)) { + hardware->hbuf[0] = atoi(&val[8]); } else { - parse_warn (cfile, - "expecting a network hardware type"); - skip_to_semi (cfile); + parse_warn(cfile, + "expecting a network hardware type"); + skip_to_semi(cfile); return; } @@ -612,34 +617,33 @@ void parse_hardware_param (cfile, hardware) that data in the lease file rather than simply failing on such clients. Yuck. */ hlen = 0; - token = peek_token (&val, (unsigned *)0, cfile); + token = peek_token(&val, NULL, cfile); if (token == SEMI) { - hardware -> hlen = 1; + hardware->hlen = 1; goto out; } - t = parse_numeric_aggregate (cfile, (unsigned char *)0, &hlen, - COLON, 16, 8); - if (!t) { - hardware -> hlen = 1; + t = parse_numeric_aggregate(cfile, NULL, &hlen, COLON, 16, 8); + if (t == NULL) { + hardware->hlen = 1; return; } - if (hlen + 1 > sizeof hardware -> hbuf) { - dfree (t, MDL); - parse_warn (cfile, "hardware address too long"); + if (hlen + 1 > sizeof(hardware->hbuf)) { + dfree(t, MDL); + parse_warn(cfile, "hardware address too long"); } else { - hardware -> hlen = hlen + 1; - memcpy ((unsigned char *)&hardware -> hbuf [1], t, hlen); - if (hlen + 1 < sizeof hardware -> hbuf) - memset (&hardware -> hbuf [hlen + 1], 0, - (sizeof hardware -> hbuf) - hlen - 1); - dfree (t, MDL); + hardware->hlen = hlen + 1; + memcpy((unsigned char *)&hardware->hbuf[1], t, hlen); + if (hlen + 1 < sizeof(hardware->hbuf)) + memset(&hardware->hbuf[hlen + 1], 0, + (sizeof(hardware->hbuf)) - hlen - 1); + dfree(t, MDL); } out: - token = next_token (&val, (unsigned *)0, cfile); + token = next_token(&val, NULL, cfile); if (token != SEMI) { - parse_warn (cfile, "expecting semicolon."); - skip_to_semi (cfile); + parse_warn(cfile, "expecting semicolon."); + skip_to_semi(cfile); } } diff --git a/common/socket.c b/common/socket.c index fa7712818..21e1f5f0a 100644 --- a/common/socket.c +++ b/common/socket.c @@ -3,7 +3,7 @@ BSD socket interface code... */ /* - * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2012 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any @@ -51,6 +51,7 @@ #include #include #include +#include #endif #ifdef USE_SOCKET_FALLBACK @@ -1067,7 +1068,7 @@ void maybe_setup_fallback () void get_hw_addr(const char *name, struct hardware *hw) { struct sockaddr_dl *dladdrp; - int rv, sock, i; + int sock, i; struct lifreq lifr; memset(&lifr, 0, sizeof (lifr)); @@ -1101,7 +1102,8 @@ get_hw_addr(const char *name, struct hardware *hw) { hw->hlen = sizeof (hw->hbuf); srandom((long)gethrtime()); - for (i = 0; i < hw->hlen; ++i) { + hw->hbuf[0] = HTYPE_IPMP; + for (i = 1; i < hw->hlen; ++i) { hw->hbuf[i] = random() % 256; } @@ -1114,8 +1116,27 @@ get_hw_addr(const char *name, struct hardware *hw) { log_fatal("Couldn't get interface hardware address for %s: %m", name); dladdrp = (struct sockaddr_dl *)&lifr.lifr_addr; - hw->hlen = dladdrp->sdl_alen; - memcpy(hw->hbuf, LLADDR(dladdrp), hw->hlen); + hw->hlen = dladdrp->sdl_alen+1; + switch (dladdrp->sdl_type) { + case DL_CSMACD: /* IEEE 802.3 */ + case DL_ETHER: + hw->hbuf[0] = HTYPE_ETHER; + break; + case DL_TPR: + hw->hbuf[0] = HTYPE_IEEE802; + break; + case DL_FDDI: + hw->hbuf[0] = HTYPE_FDDI; + break; + case DL_IB: + hw->hbuf[0] = HTYPE_INFINIBAND; + break; + default: + log_fatal("%s: unsupported DLPI MAC type %lu", name, + (unsigned long)dladdrp->sdl_type); + } + + memcpy(hw->hbuf+1, LLADDR(dladdrp), hw->hlen-1); if (sock != -1) (void) close(sock); diff --git a/common/tables.c b/common/tables.c index 10e2ce018..c820d83b2 100644 --- a/common/tables.c +++ b/common/tables.c @@ -3,6 +3,7 @@ Tables of information... */ /* + * Copyright (c) 2011-2012 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-2003 by Internet Software Consortium * @@ -601,7 +602,7 @@ const char *hardware_types [] = { "unknown-29", "unknown-30", "unknown-31", - "unknown-32", + "infiniband", "unknown-33", "unknown-34", "unknown-35", diff --git a/configure.ac b/configure.ac index 3ed50de31..f35068626 100644 --- a/configure.ac +++ b/configure.ac @@ -150,7 +150,7 @@ if test "$enable_early_chroot" = "yes" ; then [Define to any value to chroot() prior to loading config.]) fi -AC_ARG_ENABLE(IPv4_PKTINFO, +AC_ARG_ENABLE(ipv4_pktinfo, AC_HELP_STRING([--enable-ipv4-pktinfo], [enable use of pktinfo on IPv4 sockets (default is no)])) @@ -159,7 +159,7 @@ if test "$enable_ipv4_pktinfo" = "yes"; then [Define to 1 to enable IPv4 packet info support.]) fi -AC_ARG_ENABLE(USE_SOCKETS, +AC_ARG_ENABLE(use_sockets, AC_HELP_STRING([--enable-use-sockets], [use the standard BSD socket API (default is no)])) @@ -403,7 +403,7 @@ else AC_CHECK_HEADER(net/bpf.h, DO_BPF=1) if test -n "$DO_BPF" then - AC_DEFINE([HAVE_BPF], [""], + AC_DEFINE([HAVE_BPF], [1], [Define to 1 to use the Berkeley Packet Filter interface code.]) fi diff --git a/includes/dhcp.h b/includes/dhcp.h index 1af2adf87..5eb1ad8b6 100644 --- a/includes/dhcp.h +++ b/includes/dhcp.h @@ -3,6 +3,7 @@ Protocol structures... */ /* + * Copyright (c) 2011-2012 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-2003 by Internet Software Consortium * @@ -79,6 +80,10 @@ struct dhcp_packet { #define HTYPE_ETHER 1 /* Ethernet 10Mbps */ #define HTYPE_IEEE802 6 /* IEEE 802.2 Token Ring... */ #define HTYPE_FDDI 8 /* FDDI... */ +#define HTYPE_INFINIBAND 32 /* IP over Infiniband */ +#define HTYPE_IPMP 255 /* IPMP - random hw address - there + * is no standard for this so we + * just steal a type */ /* Magic cookie validating dhcp options field (and bootp vendor extensions field). */ diff --git a/includes/dhcpd.h b/includes/dhcpd.h index f0a69e98e..47f50f98f 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h @@ -436,7 +436,7 @@ struct packet { struct hardware { u_int8_t hlen; - u_int8_t hbuf [17]; + u_int8_t hbuf[21]; }; #if defined(LDAP_CONFIGURATION) diff --git a/includes/dhctoken.h b/includes/dhctoken.h index 9911d70f8..6815da4ae 100644 --- a/includes/dhctoken.h +++ b/includes/dhctoken.h @@ -3,7 +3,7 @@ Tokens for config file lexer and parser. */ /* - * Copyright (c) 2004,2007-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004,2007-2012 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any @@ -363,7 +363,8 @@ enum dhcp_token { INITIAL_DELAY = 664, GETHOSTBYNAME = 665, PRIMARY6 = 666, - SECONDARY6 = 667 + SECONDARY6 = 667, + TOKEN_INFINIBAND = 668 }; #define is_identifier(x) ((x) >= FIRST_TOKEN && \ diff --git a/server/mdb.c b/server/mdb.c index 76eb797d0..bc9fbd50a 100644 --- a/server/mdb.c +++ b/server/mdb.c @@ -3,7 +3,7 @@ Server-specific in-memory database support. */ /* - * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2012 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any @@ -1961,9 +1961,17 @@ int find_lease_by_hw_addr (struct lease **lp, const char *file, int line) { if (hwlen == 0) - return 0; - return lease_id_hash_lookup(lp, lease_hw_addr_hash, hwaddr, hwlen, - file, line); + return (0); + + /* + * If it's an infiniband address don't bother + * as we don't have a useful address to hash. + */ + if ((hwlen == 1) && (hwaddr[0] == HTYPE_INFINIBAND)) + return (0); + + return (lease_id_hash_lookup(lp, lease_hw_addr_hash, hwaddr, hwlen, + file, line)); } /* If the lease is preferred over the candidate, return truth. The @@ -2128,6 +2136,8 @@ void uid_hash_delete (lease) } /* Add the specified lease to the hardware address hash. */ +/* We don't add leases with infiniband addresses to the + * hash as there isn't any address to hash on. */ void hw_hash_add(struct lease *lease) @@ -2137,6 +2147,14 @@ hw_hash_add(struct lease *lease) struct lease *prev = NULL; struct lease *next = NULL; + /* + * If it's an infiniband address don't bother + * as we don't have a useful address to hash. + */ + if ((lease->hardware_addr.hlen == 1) && + (lease->hardware_addr.hbuf[0] == HTYPE_INFINIBAND)) + return; + /* If it's not in the hash, just add it. */ if (!find_lease_by_hw_addr (&head, lease -> hardware_addr.hbuf, lease -> hardware_addr.hlen, MDL)) @@ -2208,6 +2226,14 @@ void hw_hash_delete (lease) struct lease *head = (struct lease *)0; struct lease *next = (struct lease *)0; + /* + * If it's an infiniband address don't bother + * as we don't have a useful address to hash. + */ + if ((lease->hardware_addr.hlen == 1) && + (lease->hardware_addr.hbuf[0] == HTYPE_INFINIBAND)) + return; + /* If it's not in the hash, we have no work to do. */ if (!find_lease_by_hw_addr (&head, lease -> hardware_addr.hbuf, lease -> hardware_addr.hlen, MDL)) {