ir = 0;
else if (state == DISCOVER_UNCONFIGURED)
ir = INTERFACE_REQUESTED | INTERFACE_AUTOMATIC;
- else
+ else {
ir = INTERFACE_REQUESTED;
+ if (state == DISCOVER_RELAY && local_family == AF_INET) {
+ /* We're a v4 relay without specifically requested
+ * interfaces, so mark them all as bidirectional. */
+ ir |= INTERFACE_STREAMS;
+ }
+ }
/* Cycle through the list of interfaces looking for IP addresses. */
while (next_iface(&info, &err, &ifaces)) {
[
.B ...
.B -i
+.I interfaceN
+]
+]
+[
+.B -iu
+.I interface0
+[
+.B ...
+.B -iu
.I interfaceN
]
]
specified, such packets will be relayed anyway.
.TP
-i \fIifname\fR
-Listen for DHCPv4/BOOTP queries on interface \fIifname\fR. Multiple
+Listen for DHCPv4/BOOTP traffic on interface \fIifname\fR. Multiple
interfaces may be specified by using more than one \fB-i\fR option. If
no interfaces are specified on the command line, dhcrelay will identify
all network interfaces, eliminating non-broadcast interfaces if possible,
and attempt to listen on all of them.
.TP
+-iu \fIifname\fR
+Specifies an upstream network interface for DHCPv4 relay mode: an
+interface from which replies from servers and other relay agents will be
+accepted. Multiple interfaces may be specified by using more
+than one \fB-u\fR option. This argument is intended to be used
+in conjunction with one or more -i arguments.
+.TP
-m \fIappend\fR|\fIreplace\fR|\fIforward\fR|\fIdiscard\fR
Control the handling of incoming DHCPv4 packets which already contain
relay agent options. If such a packet does not have \fIgiaddr\fR set in
" [-pf <pid-file>] [--no-pid]\n"\
" [-m append|replace|forward|discard]\n" \
" [-i interface0 [ ... -i interfaceN]\n" \
+" [-ui interface0 [ ... -ui interfaceN]\n" \
" server0 [ ... serverN]\n\n" \
" %s -6 [-d] [-q] [-I] [-c <hops>] [-p <port>]\n" \
" [-pf <pid-file>] [--no-pid]\n"\
" [-pf <pid-file>] [--no-pid]\n"\
" [-m append|replace|forward|discard]\n" \
" [-i interface0 [ ... -i interfaceN]\n" \
+" [-ui interface0 [ ... -ui interfaceN]\n" \
" server0 [ ... serverN]\n\n"
#endif
isc_result_totext(status));
}
strcpy(tmp->name, argv[i]);
- interface_snorf(tmp, INTERFACE_REQUESTED);
+ interface_snorf(tmp, (INTERFACE_REQUESTED
+ | INTERFACE_STREAMS));
+ interface_dereference(&tmp, MDL);
+ } else if (!strcmp(argv[i], "-iu")) {
+#ifdef DHCPv6
+ if (local_family_set && (local_family == AF_INET6)) {
+ usage(use_v4command, argv[i]);
+ }
+ local_family_set = 1;
+ local_family = AF_INET;
+#endif
+ if (++i == argc) {
+ usage(use_noarg, argv[i-1]);
+ }
+ if (strlen(argv[i]) >= sizeof(tmp->name)) {
+ log_fatal("%s: interface name too long "
+ "(is %ld)",
+ argv[i], (long)strlen(argv[i]));
+ }
+ status = interface_allocate(&tmp, MDL);
+ if (status != ISC_R_SUCCESS) {
+ log_fatal("%s: interface_allocate: %s",
+ argv[i],
+ isc_result_totext(status));
+ }
+ strcpy(tmp->name, argv[i]);
+ interface_snorf(tmp, (INTERFACE_REQUESTED
+ | INTERFACE_UPSTREAM));
interface_dereference(&tmp, MDL);
} else if (!strcmp(argv[i], "-a")) {
#ifdef DHCPv6
/* If it's a bootreply, forward it to the client. */
if (packet->op == BOOTREPLY) {
+ if (!(ip->flags & INTERFACE_UPSTREAM)) {
+ log_debug("Dropping reply received on %s", ip->name);
+ return;
+ }
+
if (!(packet->flags & htons(BOOTP_BROADCAST)) &&
can_unicast_without_arp(out)) {
to.sin_addr = packet->yiaddr;