summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Markwalder <tmark@isc.org>2015-01-19 13:40:25 -0500
committerThomas Markwalder <tmark@isc.org>2015-01-19 13:40:25 -0500
commitaccb28721d061f2e06e927bdb1337317db3aa706 (patch)
tree00d8e2b41019e841c99dbe78b94f68a96e41c70a
parent9d20107ee3eed7856f7d06eb41ee9b8942168688 (diff)
downloadisc-dhcp-accb28721d061f2e06e927bdb1337317db3aa706.tar.gz
[v4_2] Fixed inconsistencies in setting hop count limit in dhcrelay
Merges in rt37426.
-rw-r--r--RELNOTES9
-rw-r--r--common/socket.c24
-rw-r--r--includes/dhcpd.h2
-rw-r--r--relay/dhcrelay.c17
4 files changed, 39 insertions, 13 deletions
diff --git a/RELNOTES b/RELNOTES
index 6d6eed06..b5d3dfcd 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -186,6 +186,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.2.7rc1
- None
diff --git a/common/socket.c b/common/socket.c
index c1704480..5467a35b 100644
--- a/common/socket.c
+++ b/common/socket.c
@@ -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)
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
index 2b154306..bd11b486 100644
--- a/includes/dhcpd.h
+++ b/includes/dhcpd.h
@@ -2386,6 +2386,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)
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
index 927e4048..ad76d3e4 100644
--- a/relay/dhcrelay.c
+++ b/relay/dhcrelay.c
@@ -1173,8 +1173,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;
}
@@ -1192,8 +1192,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);
@@ -1244,6 +1244,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;
}
@@ -1261,8 +1263,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);
@@ -1330,6 +1332,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);
+ }
}
}