diff options
author | Thomas Markwalder <tmark@isc.org> | 2015-01-19 13:40:25 -0500 |
---|---|---|
committer | Thomas Markwalder <tmark@isc.org> | 2015-01-19 13:40:25 -0500 |
commit | accb28721d061f2e06e927bdb1337317db3aa706 (patch) | |
tree | 00d8e2b41019e841c99dbe78b94f68a96e41c70a | |
parent | 9d20107ee3eed7856f7d06eb41ee9b8942168688 (diff) | |
download | isc-dhcp-accb28721d061f2e06e927bdb1337317db3aa706.tar.gz |
[v4_2] Fixed inconsistencies in setting hop count limit in dhcrelay
Merges in rt37426.
-rw-r--r-- | RELNOTES | 9 | ||||
-rw-r--r-- | common/socket.c | 24 | ||||
-rw-r--r-- | includes/dhcpd.h | 2 | ||||
-rw-r--r-- | relay/dhcrelay.c | 17 |
4 files changed, 39 insertions, 13 deletions
@@ -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); + } } } |