philipp / rpms / dhcp

Forked from rpms/dhcp 4 years ago
Clone

Blame SOURCES/dhcp-hop-limit.patch

45d60a
From accb28721d061f2e06e927bdb1337317db3aa706 Mon Sep 17 00:00:00 2001
45d60a
From: Thomas Markwalder <tmark@isc.org>
45d60a
Date: Mon, 19 Jan 2015 13:40:25 -0500
45d60a
Subject: [PATCH] [v4_2] Fixed inconsistencies in setting hop count limit in
45d60a
 dhcrelay
45d60a
45d60a
diff --git a/common/socket.c b/common/socket.c
45d60a
index c170448..5467a35 100644
45d60a
--- a/common/socket.c
45d60a
+++ b/common/socket.c
45d60a
@@ -300,18 +300,24 @@ if_register_socket(struct interface_info *info, int family,
45d60a
 #endif
45d60a
 	}
45d60a
 
45d60a
-	if ((family == AF_INET6) &&
45d60a
-	    ((info->flags & INTERFACE_UPSTREAM) != 0)) {
45d60a
-		int hop_limit = 32;
45d60a
-		if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
45d60a
-			       &hop_limit, sizeof(int)) < 0) {
45d60a
-			log_fatal("setsockopt: IPV6_MULTICAST_HOPS: %m");
45d60a
-		}
45d60a
-	}
45d60a
 #endif /* DHCPv6 */
45d60a
 
45d60a
 	return sock;
45d60a
 }
45d60a
+
45d60a
+#ifdef DHCPv6
45d60a
+void set_multicast_hop_limit(struct interface_info* info, int hop_limit) {
45d60a
+	if (setsockopt(info->wfdesc, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
45d60a
+		       &hop_limit, sizeof(int)) < 0) {
45d60a
+		log_fatal("setMulticaseHopLimit: IPV6_MULTICAST_HOPS: %m");
45d60a
+	}
45d60a
+
45d60a
+	log_debug("Setting hop count limit to %d for interface %s",
45d60a
+		  hop_limit, info->name);
45d60a
+
45d60a
+}
45d60a
+#endif /* DHCPv6 */
45d60a
+
45d60a
 #endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE || USE_SOCKET_FALLBACK */
45d60a
 
45d60a
 #if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_FALLBACK)
45d60a
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
45d60a
index 2b15430..bd11b48 100644
45d60a
--- a/includes/dhcpd.h
45d60a
+++ b/includes/dhcpd.h
45d60a
@@ -2386,6 +2386,8 @@ void get_hw_addr(const char *name, struct hardware *hw);
45d60a
 #if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE) \
45d60a
 	|| defined (USE_SOCKET_FALLBACK)
45d60a
 int if_register_socket(struct interface_info *, int, int *, struct in6_addr *);
45d60a
+
45d60a
+void set_multicast_hop_limit(struct interface_info* info, int hop_limit);
45d60a
 #endif
45d60a
 
45d60a
 #if defined (USE_SOCKET_FALLBACK) && !defined (USE_SOCKET_SEND)
45d60a
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
45d60a
index 927e404..ad76d3e 100644
45d60a
--- a/relay/dhcrelay.c
45d60a
+++ b/relay/dhcrelay.c
45d60a
@@ -1173,8 +1173,8 @@ parse_downstream(char *arg) {
45d60a
 	/* Share with up side? */
45d60a
 	for (up = upstreams; up; up = up->next) {
45d60a
 		if (strcmp(ifname, up->ifp->name) == 0) {
45d60a
-			log_info("Interface '%s' is both down and up.",
45d60a
-				 ifname);
45d60a
+			log_info("parse_downstream: Interface '%s' is "
45d60a
+				 "both down and up.", ifname);
45d60a
 			ifp = up->ifp;
45d60a
 			break;
45d60a
 		}
45d60a
@@ -1192,8 +1192,8 @@ parse_downstream(char *arg) {
45d60a
 			interface_dereference(&interfaces, MDL);
45d60a
 		}
45d60a
 		interface_reference(&interfaces, ifp, MDL);
45d60a
-		ifp->flags |= INTERFACE_REQUESTED | INTERFACE_DOWNSTREAM;
45d60a
 	}
45d60a
+	ifp->flags |= INTERFACE_REQUESTED | INTERFACE_DOWNSTREAM;
45d60a
 
45d60a
 	/* New downstream. */
45d60a
 	dp = (struct stream_list *) dmalloc(sizeof(*dp), MDL);
45d60a
@@ -1244,6 +1244,8 @@ parse_upstream(char *arg) {
45d60a
 	}
45d60a
 	for (dp = downstreams; dp; dp = dp->next) {
45d60a
 		if (strcmp(ifname, dp->ifp->name) == 0) {
45d60a
+			log_info("parse_upstream: Interface '%s' is "
45d60a
+				 "both down and up.", ifname);
45d60a
 			ifp = dp->ifp;
45d60a
 			break;
45d60a
 		}
45d60a
@@ -1261,8 +1263,8 @@ parse_upstream(char *arg) {
45d60a
 			interface_dereference(&interfaces, MDL);
45d60a
 		}
45d60a
 		interface_reference(&interfaces, ifp, MDL);
45d60a
-		ifp->flags |= INTERFACE_REQUESTED | INTERFACE_UPSTREAM;
45d60a
 	}
45d60a
+	ifp->flags |= INTERFACE_REQUESTED | INTERFACE_UPSTREAM;
45d60a
 
45d60a
 	/* New upstream. */
45d60a
 	up = (struct stream_list *) dmalloc(sizeof(*up), MDL);
45d60a
@@ -1330,6 +1332,13 @@ setup_streams(void) {
45d60a
 		if (up->ifp->v6address_count == 0)
45d60a
 			log_fatal("Interface '%s' has no IPv6 addresses.",
45d60a
 				  up->ifp->name);
45d60a
+
45d60a
+		/* RFC 3315 Sec 20 - "If the relay agent relays messages to
45d60a
+		 * the All_DHCP_Servers address or other multicast addresses,
45d60a
+		 * it sets the Hop Limit field to 32." */
45d60a
+		if (IN6_IS_ADDR_MULTICAST(&up->link.sin6_addr)) {
45d60a
+			set_multicast_hop_limit(up->ifp, HOP_COUNT_LIMIT);
45d60a
+		}
45d60a
 	}
45d60a
 }
45d60a
 
45d60a
-- 
45d60a
2.1.0
45d60a