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

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

index 1fee22e418325dc6c021a620c283590bbcbd2610..6a54b92a5b3c7fa48c15a811eef55f994a44550d 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -181,6 +181,15 @@ by Eric Young (eay@cryptsoft.com).
   [ISC-Bugs #36668]
   [ISC-Bugs #36652]
 
+- 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.1-ESV-R10rc1
 
 - None
index db10db08a8974f6434ae0ca14165b93f62912be7..c49317a05de1c5619c6f0ca953fcb1aa3a694cf7 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
@@ -294,18 +294,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 94257794e87ef1ec772a6f502e704a793f7b8cc3..d374aa36176e4509edc919181d5187f4a00b642d 100644 (file)
@@ -2187,6 +2187,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 17adcc1603ddd3824ef57025b3a531c42f19ae70..5e5a6fb49004809fd6f375876119bea4228431fc 100644 (file)
@@ -1168,8 +1168,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;
                }
@@ -1187,8 +1187,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);
@@ -1239,6 +1239,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;
                }
@@ -1256,8 +1258,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);
@@ -1325,6 +1327,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);
+               }
        }
 }