]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[master] Added -iu command line argument to dhcrelay
authorThomas Markwalder <tmark@isc.org>
Wed, 10 Aug 2016 18:31:26 +0000 (14:31 -0400)
committerThomas Markwalder <tmark@isc.org>
Wed, 10 Aug 2016 18:31:26 +0000 (14:31 -0400)
    Merges in 41547a

RELNOTES
common/discover.c
relay/dhcrelay.8
relay/dhcrelay.c

index 89febc8c3a38b7e6c63e3e56b97c430edf6b8fa3..730a62561b54d8477d736c08eb88b681574b983d 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -872,6 +872,10 @@ by Eric Young (eay@cryptsoft.com).
   it runs out.
   [ISC-Bugs #42452]
 
+- Add a new command line option, "-iu", to dhcrelay which allows one
+  or more interfaces to be regisetered to listen only for BOOTP replies.
+  [ISC-Bugs #41547]
+
                        Changes since 4.2.0 (new features)
 
 - If a client renews before 'dhcp-cache-threshold' percent of its lease
index 5930eaa97c0d9802fd49080567544d2b1b7c72a4..8e7f6328a9ec707b6137aa1e752464dcb229727e 100644 (file)
@@ -950,8 +950,14 @@ discover_interfaces(int state) {
                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)) {
index 67065663d906616569d9fb7d459d8d8e1a2ec6d3..1091edb7ea4d7e82866b347145becf622cd5602c 100644 (file)
@@ -77,6 +77,14 @@ dhcrelay - Dynamic Host Configuration Protocol Relay Agent
 .B -i
 .I interfaceN 
 ]
+[
+.B -iu
+.I interface0
+[
+.B ...
+.B -iu
+.I interfaceN
+]
 .B -l
 .I interface
 ]
@@ -204,12 +212,19 @@ a query that came via a different relay agent.  If this option is not
 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
index c72d6f31aa9e97604438e7cdbe8193f1aaa133c6..4127fccc20a45fe2b0a79e89c5d20df804afea4c 100644 (file)
@@ -153,6 +153,7 @@ char *progname;
 "                     [-pf <pid-file>] [--no-pid]\n"\
 "                     [-m append|replace|forward|discard]\n" \
 "                     [-i interface0 [ ... -i interfaceN]\n" \
+"                     [-iu interface0 [ ... -iu interfaceN]\n" \
 "                     [-U interface]\n" \
 "                     server0 [ ... serverN]\n\n" \
 "       %s -6   [-d] [-q] [-I] [-c <hops>] [-p <port>]\n" \
@@ -168,6 +169,7 @@ char *progname;
 "                [-pf <pid-file>] [--no-pid]\n" \
 "                [-m append|replace|forward|discard]\n" \
 "                [-i interface0 [ ... -i interfaceN]\n" \
+"                [-iu interface0 [ ... -iu interfaceN]\n" \
 "                [-U interface]\n" \
 "                server0 [ ... serverN]\n\n"
 #endif
@@ -325,7 +327,34 @@ main(int argc, char **argv) {
                                          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
@@ -398,7 +427,8 @@ main(int argc, char **argv) {
                        uplink->name[sizeof(uplink->name) - 1] = 0x00;
                        strncpy(uplink->name, argv[i],
                                sizeof(uplink->name) - 1);
-                       interface_snorf(uplink, INTERFACE_REQUESTED);
+                       interface_snorf(uplink, (INTERFACE_REQUESTED |
+                                               INTERFACE_STREAMS));
 
                        /* Turn on -a, in case they don't do so explicitly */
                        add_agent_options = 1;
@@ -730,6 +760,11 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet,
 
        /* 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;