[PATCH 5/6] dhcrelay: Support RFC6221 Lightweight DHCPv6 Relay Agent operation

Bjørn Mork bjorn at mork.no
Sun Sep 25 12:59:48 UTC 2011


There really isn't much required for layer2 operation.  Just set the
link address to :: and you're basically done.

Signed-off-by: Bjørn Mork <bjorn at mork.no>
---
 relay/dhcrelay.8 |   18 ++++++++++++++----
 relay/dhcrelay.c |   28 +++++++++++++++++++++-------
 2 files changed, 35 insertions(+), 11 deletions(-)

diff --git a/relay/dhcrelay.8 b/relay/dhcrelay.8
index 06408a3..c4115cb 100644
--- a/relay/dhcrelay.8
+++ b/relay/dhcrelay.8
@@ -86,7 +86,7 @@ dhcrelay - Dynamic Host Configuration Protocol Relay Agent
 .PP
 .B dhcrelay -6
 [
-.B -dqI
+.B -dqIL
 ]
 [
 .B -p
@@ -225,6 +225,15 @@ in use, to disambiguate between them.  The \fB-I\fR option causes
 dhcrelay to send the option even if there is only one downstream
 interface.
 .TP
+-L
+Enable Lightweight DHCPv6 Relay Agent (layer 2) operation according to
+RFC6221.  This forces the \fB-I\fR option on, and uses the unspecified
+address (::) as link address in all relayed packets, enabling operation
+on a layer 2 brigde with no global address at all. Note that this
+option makes both the \fB-I\fR option and the \fIaddress%\fR parameter
+of the \fB-l\fR option redundant.  Any configured \fIaddress%\fR will
+be silently ignored.
+.TP
 -e \fIenterprisenumber\fR
 Specifies the IANA allocated enterprise number to be used in REMOTE-ID
 options.  Required for adding REMOTE-ID
@@ -236,9 +245,10 @@ relay agents.  At least one \fB-l\fR option must be included in the command
 line when running in DHCPv6 mode.  The interface name \fIifname\fR is a
 mandatory parameter.  The link address can be specified by \fIaddress%\fR;
 if it isn't, dhcrelay will use the first non-link-local address configured
-on the interface.  The optional \fI#index\fR parameter specifies the
-interface index. The optional \fI!remoteid\fR parameter specifies the
-ascii remote id value (requires the \fB-e\fR option as well).
+on the interface unless configured for LDRA with the \fB-L\fR option.
+The optional \fI#index\fR parameter specifies the interface index. The
+optional \fI!remoteid\fR parameter specifies the ascii remote id value
+(requires the \fB-e\fR option as well).
 .TP
 -u [\fIaddress%\fR]\fIifname\fR
 Specifies the ``upper'' network interface for DHCPv6 relay mode: the
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
index 780b59a..f00aa2f 100644
--- a/relay/dhcrelay.c
+++ b/relay/dhcrelay.c
@@ -83,6 +83,7 @@ int max_hop_count = 10;		/* Maximum hop count */
 #ifdef DHCPv6
 	/* Force use of DHCPv6 interface-id option. */
 isc_boolean_t use_if_id = ISC_FALSE;
+isc_boolean_t rfc6221_ldra = ISC_FALSE; /* implement RFC6221 LDRA */
 #endif
 
 	/* Maximum size of a packet with agent options added. */
@@ -150,7 +151,7 @@ static const char url[] =
 "                     [-m append|replace|forward|discard]\n" \
 "                     [-i interface0 [ ... -i interfaceN]\n" \
 "                     server0 [ ... serverN]\n\n" \
-"       dhcrelay -6   [-d] [-q] [-I] [-c <hops>] [-p <port>]\n" \
+"       dhcrelay -6   [-d] [-q] [-I] [-L] [-c <hops>] [-p <port>]\n" \
 "                     [-pf <pid-file>] [--no-pid]\n"\
 "                     -e <enterprisenumber>\n"\
 "                     -l lower0 [ ... -l lowerN]\n" \
@@ -337,6 +338,14 @@ main(int argc, char **argv) {
 			local_family_set = 1;
 			local_family = AF_INET6;
 			use_if_id = ISC_TRUE;
+		} else if (!strcmp(argv[i], "-L")) {
+			if (local_family_set && (local_family == AF_INET)) {
+				usage();
+			}
+			local_family_set = 1;
+			local_family = AF_INET6;
+			rfc6221_ldra = ISC_TRUE;
+			use_if_id = ISC_TRUE; /* required by RFC6221 */
 		} else if (!strcmp(argv[i], "-e")) {
 			if (local_family_set && (local_family == AF_INET)) {
 				usage();
@@ -1223,8 +1232,9 @@ parse_downstream(char *arg) {
 		dp->ifp->remote_id_len = sizeof(int) + strlen(rid);
 	}
 	/* !addr case handled by setup. */
-	if (addr && (inet_pton(AF_INET6, addr, &dp->link.sin6_addr) <= 0))
-		log_fatal("Bad link address '%s'", addr);
+	if (!rfc6221_ldra && /* silently ignore any addr for LDRA */
+		addr && (inet_pton(AF_INET6, addr, &dp->link.sin6_addr) <= 0))
+			log_fatal("Bad link address '%s'", addr);
 
 	return dp;
 }
@@ -1304,6 +1314,14 @@ setup_streams(void) {
 	isc_boolean_t link_is_set;
 
 	for (dp = downstreams; dp; dp = dp->next) {
+		/* Set interface-id. */
+		if (dp->id == -1)
+			dp->id = htonl(dp->ifp->index);
+
+		/* link address must be :: for LDRA according to RFC6221 */
+		if (rfc6221_ldra)
+			continue;
+
 		/* Check interface */
 		if (dp->ifp->v6address_count == 0)
 			log_fatal("Interface '%s' has no IPv6 addresses.",
@@ -1331,10 +1349,6 @@ setup_streams(void) {
 			memcpy(&dp->link.sin6_addr,
 			       &dp->ifp->v6addresses[i],
 			       sizeof(dp->link.sin6_addr));
-
-		/* Set interface-id. */
-		if (dp->id == -1)
-			dp->id = htonl(dp->ifp->index);
 	}
 
 	for (up = upstreams; up; up = up->next) {
-- 
1.7.2.5




More information about the dhcp-users mailing list