aboutsummaryrefslogtreecommitdiff
path: root/relay/dhcrelay.c
diff options
context:
space:
mode:
Diffstat (limited to 'relay/dhcrelay.c')
-rw-r--r--relay/dhcrelay.c28
1 files changed, 21 insertions, 7 deletions
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) {