]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[master] Fixed inconsistencies in setting hop count limit in dhcrelay
authorThomas Markwalder <tmark@isc.org>
Mon, 19 Jan 2015 18:25:18 +0000 (13:25 -0500)
committerThomas Markwalder <tmark@isc.org>
Mon, 19 Jan 2015 18:25:18 +0000 (13:25 -0500)
    Merges in rt37426.

RELNOTES
common/socket.c
includes/dhcpd.h
relay/dhcrelay.c

index a57622e8f8cc45cf2870dad7e1e813b363bce788..aff13dd220cf4a738481ec951cbeb579b9fc9b6e 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -246,6 +246,15 @@ by Eric Young (eay@cryptsoft.com).
   [ISC-Bugs #36780]
   [ISC-Bugs #32228]
 
+- Corrected inconsistencies in dhcrelay's setting the upper interface hop count
+  limit such that it now sets it to 32 when the upstream address is a multicast
+  address per RFC 3315 Section 20. Prior to this if the -u argument preceded
+  the -l argument on the command line or if the same interface was specified
+  for both; the logic to set the hop limit count for the upper interface was
+  skipped.  This caused the hop count limit to be set to the default value
+  (typically 1) in the outbound upstream packets.
+  [ISC-Bugs #37426]
+
                        Changes since 4.3.1b1
 
 - Modify the linux and openwrt dhclient scripts to process information
index b8b44a67215e7a09a27d0d15590662b90be8df89..e8851b4cfa05424c6c0a4c8a69d6c47371c1657d 100644 (file)
@@ -3,7 +3,7 @@
    BSD socket interface code... */
 
 /*
- * Copyright (c) 2004-2014 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2015 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
@@ -300,18 +300,24 @@ if_register_socket(struct interface_info *info, int family,
 #endif
        }
 
-       if ((family == AF_INET6) &&
-           ((info->flags & INTERFACE_UPSTREAM) != 0)) {
-               int hop_limit = 32;
-               if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
-                              &hop_limit, sizeof(int)) < 0) {
-                       log_fatal("setsockopt: IPV6_MULTICAST_HOPS: %m");
-               }
-       }
 #endif /* DHCPv6 */
 
        return sock;
 }
+
+#ifdef DHCPv6
+void set_multicast_hop_limit(struct interface_info* info, int hop_limit) {
+       if (setsockopt(info->wfdesc, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
+                      &hop_limit, sizeof(int)) < 0) {
+               log_fatal("setMulticaseHopLimit: IPV6_MULTICAST_HOPS: %m");
+       }
+
+       log_debug("Setting hop count limit to %d for interface %s",
+                 hop_limit, info->name);
+
+}
+#endif /* DHCPv6 */
+
 #endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE || USE_SOCKET_FALLBACK */
 
 #if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_FALLBACK)
index 7bf8a4560a5a0ab654ab3d27fe948df4fb092a30..3d036a920f3863db60e9e2f2e11712008af5cf8d 100644 (file)
@@ -2477,6 +2477,8 @@ void get_hw_addr(const char *name, struct hardware *hw);
 #if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE) \
        || defined (USE_SOCKET_FALLBACK)
 int if_register_socket(struct interface_info *, int, int *, struct in6_addr *);
+
+void set_multicast_hop_limit(struct interface_info* info, int hop_limit);
 #endif
 
 #if defined (USE_SOCKET_FALLBACK) && !defined (USE_SOCKET_SEND)
index 4da7e864511f3f80ea5a05531d9a8967c6994e82..4d1d6fd221f5e6c83e512115c4f218edf7861e8b 100644 (file)
@@ -1192,8 +1192,8 @@ parse_downstream(char *arg) {
        /* Share with up side? */
        for (up = upstreams; up; up = up->next) {
                if (strcmp(ifname, up->ifp->name) == 0) {
-                       log_info("Interface '%s' is both down and up.",
-                                ifname);
+                       log_info("parse_downstream: Interface '%s' is "
+                                "both down and up.", ifname);
                        ifp = up->ifp;
                        break;
                }
@@ -1211,8 +1211,8 @@ parse_downstream(char *arg) {
                        interface_dereference(&interfaces, MDL);
                }
                interface_reference(&interfaces, ifp, MDL);
-               ifp->flags |= INTERFACE_REQUESTED | INTERFACE_DOWNSTREAM;
        }
+       ifp->flags |= INTERFACE_REQUESTED | INTERFACE_DOWNSTREAM;
 
        /* New downstream. */
        dp = (struct stream_list *) dmalloc(sizeof(*dp), MDL);
@@ -1263,6 +1263,8 @@ parse_upstream(char *arg) {
        }
        for (dp = downstreams; dp; dp = dp->next) {
                if (strcmp(ifname, dp->ifp->name) == 0) {
+                       log_info("parse_upstream: Interface '%s' is "
+                                "both down and up.", ifname);
                        ifp = dp->ifp;
                        break;
                }
@@ -1280,8 +1282,8 @@ parse_upstream(char *arg) {
                        interface_dereference(&interfaces, MDL);
                }
                interface_reference(&interfaces, ifp, MDL);
-               ifp->flags |= INTERFACE_REQUESTED | INTERFACE_UPSTREAM;
        }
+       ifp->flags |= INTERFACE_REQUESTED | INTERFACE_UPSTREAM;
 
        /* New upstream. */
        up = (struct stream_list *) dmalloc(sizeof(*up), MDL);
@@ -1349,6 +1351,13 @@ setup_streams(void) {
                if (up->ifp->v6address_count == 0)
                        log_fatal("Interface '%s' has no IPv6 addresses.",
                                  up->ifp->name);
+
+               /* RFC 3315 Sec 20 - "If the relay agent relays messages to
+                * the All_DHCP_Servers address or other multicast addresses,
+                * it sets the Hop Limit field to 32." */
+               if (IN6_IS_ADDR_MULTICAST(&up->link.sin6_addr)) {
+                       set_multicast_hop_limit(up->ifp, HOP_COUNT_LIMIT);
+               }
        }
 }