diff options
Diffstat (limited to 'relay/dhcrelay.c')
-rw-r--r-- | relay/dhcrelay.c | 28 |
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) { |