]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Add support for Infiniband over sockets to the server and
authorShawn Routhier <sar@isc.org>
Thu, 16 Feb 2012 21:02:03 +0000 (21:02 +0000)
committerShawn Routhier <sar@isc.org>
Thu, 16 Feb 2012 21:02:03 +0000 (21:02 +0000)
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]

RELNOTES
common/conflex.c
common/packet.c
common/parse.c
common/socket.c
common/tables.c
configure.ac
includes/dhcp.h
includes/dhcpd.h
includes/dhctoken.h
server/mdb.c

index 1bbf4025f1543eb3e865fa8127e9fdd327c99795..e80ba226a45eb8757dbc3de5612d29c24ccd149f 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -62,6 +62,11 @@ 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.1-ESV-R3
 
 - Add AM_MAINTAINER_MODE to configure.ac to avoid rebuilding
index ff2cf64af20ca2f84a71a98342c65f30004b320c..57058e923718ba87a71368dbe62d8ac822ff5ccc 100644 (file)
@@ -3,7 +3,8 @@
    Lexical scanner for dhcpd config file... */
 
 /*
- * Copyright (c) 2004-2009,2011 by Internet Systems Consortium, Inc. ("ISC")
+ * 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
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -1004,6 +1005,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"))
index 42bca69c5abb64a0390f2ee4774a4987f7c38126..45e96e82c382e348915e565aa04dee417a8af79b 100644 (file)
@@ -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. */
index 1691fd244a34347722fc5d06216a67dd9686ea95..1a0ef150b781969f418c9a5955fffffe7705a5a0 100644 (file)
@@ -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);
        }
 }
 
index 4126e24a621c7b5c9789c67eec1a284ed4314ba9..a6f693f347251bc7febd600e2d8663baf326599b 100644 (file)
@@ -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
@@ -52,6 +52,7 @@
 #include <net/if.h>
 #include <sys/sockio.h>
 #include <net/if_dl.h>
+#include <sys/dlpi.h>
 #endif
 
 #ifdef USE_SOCKET_FALLBACK
@@ -1061,7 +1062,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));
@@ -1095,7 +1096,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;
                }
 
@@ -1108,8 +1110,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);
index db051a79fdc746ab12b44d709ddaf3270e00c762..fccce67558691f2760e9175c65ae6ebc69cf440b 100644 (file)
@@ -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
  *
@@ -596,7 +597,7 @@ const char *hardware_types [] = {
        "unknown-29",
        "unknown-30",
        "unknown-31",
-       "unknown-32",
+       "infiniband",
        "unknown-33",
        "unknown-34",
        "unknown-35",
index f1f2b941cc7309a767a39ca0e128865b8451ece9..5c7ec863e7ed70b3ca25910571814690bc0bed2b 100644 (file)
@@ -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
index 1af2adf87564051ea22e5e6af0f33ac63de56c33..5eb1ad8b6a2fffa527ecb15e54071b12499d832b 100644 (file)
@@ -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). */
index 7c36dae6b1b43d421f5d9f9e537770d9a33d800e..afebbe0f4ec03b85bab943e5196037880a083dc9 100644 (file)
@@ -3,7 +3,7 @@
    Definitions for dhcpd... */
 
 /*
- * 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
@@ -421,7 +421,7 @@ struct packet {
 
 struct hardware {
        u_int8_t hlen;
-       u_int8_t hbuf [17];
+       u_int8_t hbuf[21];
 };
 
 typedef enum {
index d96d32c6fc3b91c16e20c38981b5693cd1b24bf8..7c4ffb75354ea09732c2ce427436eee0804b5abb 100644 (file)
@@ -3,7 +3,7 @@
    Tokens for config file lexer and parser. */
 
 /*
- * Copyright (c) 2011 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2011-2012 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 2004,2007-2009 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 1996-2003 by Internet Software Consortium
  *
@@ -358,7 +358,8 @@ enum dhcp_token {
        FIXED_PREFIX6 = 658,
        CONFLICT_DONE = 660,
        INITIAL_DELAY = 664,
-       GETHOSTBYNAME = 665
+       GETHOSTBYNAME = 665,
+       TOKEN_INFINIBAND = 668
 };
 
 #define is_identifier(x)       ((x) >= FIRST_TOKEN &&  \
index d93623775bb7b2ca1907fb8243b2dd6fdde8b5c3..0965ba703553a43ef61447807292235344b63824 100644 (file)
@@ -3,6 +3,7 @@
    Server-specific in-memory database support. */
 
 /*
+ * Copyright (c) 2011-2012 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 1996-2003 by Internet Software Consortium
  *
@@ -1882,9 +1883,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
@@ -2049,6 +2058,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)
@@ -2058,6 +2069,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))
@@ -2129,6 +2148,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)) {