Bug 2169355

Summary: Backport - Fix removal of DHCP_CLIENT_MAC options from DHCPv6 relay replies.
Product: Red Hat Enterprise Linux 8 Reporter: Harald Jensås <hjensas>
Component: dnsmasqAssignee: Petr Menšík <pemensik>
Status: CLOSED ERRATA QA Contact: rhel-cs-infra-services-qe <rhel-cs-infra-services-qe>
Severity: high Docs Contact:
Priority: urgent    
Version: 8.2CC: aruffin, mmatsuya, psklenar
Target Milestone: rcKeywords: TestCaseProvided, Triaged, ZStream
Target Release: ---Flags: pm-rhel: mirror+
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: dnsmasq-2.79-26.el8 Doc Type: No Doc Update
Doc Text:
Dnsmasq no longer sends Client Link-Layer Address option in relayed DHCPv6 reply.
Story Points: ---
Clone Of:
: 2172357 2172358 2172359 (view as bug list) Environment:
Last Closed: 2023-05-16 08:43:38 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 2154717, 2172357, 2172358, 2172359    

Description Harald Jensås 2023-02-13 12:09:24 UTC
Description of problem:
DHCPv6 relay replies from dnsmasq acting as DHCPv6 server are dropped by the relay agent on the router because DHCP_CLIENT_MAC (Option 79) with a invalid lenght of 0 is in the relay reply.

Upstream dnsmasq fixed the issue in commit: f8c77edbdffb8ada7753ea9fa104f0f6da70cfe3


Version-Release number of selected component (if applicable):
dnsmasq-2.79-11.el8_2.2.x86_64

How reproducible:
100%

Steps to Reproduce:
1. Set up dnsmasq DHCPv6 server
2. Configure relay agent on JunOS router
3. Attempt DHCPv6 from client on the client side of the relay.

We can reproduce with any relay agent, and confirm 0 lenght DHCP_CLIENT_MAC in reply by means of traffic capture.

Actual results:
dnsmasq recives the relay-forward from JunOS and sends the relay-reply with DHCP_CLIENT_MAC of 0 lenght included. The JunOS device drops the relay-reply and logs that the packet was dropped because of invalid DHCP_CLIENT_MAC option lenght.

Expected results:
dmsmasq should not include the DHCP_CLIENT_MAC option in relay-reply.

Additional info:
https://www.rfc-editor.org/rfc/rfc6939.html

6.  DHCPv6 Server Behavior

   If the DHCPv6 server is configured to store or use a client link-
   layer address, it SHOULD look for the Client Link-Layer Address
   option in the Relay-Forward DHCP message of the DHCPv6 relay agent
   closest to the client.  The mechanism described in this document is
   not necessary in the case where the DHCPv6 server is connected to the
   same network link as the client, because the server can obtain the
   link-layer address from the link-layer header of the DHCPv6 message.
   If the DHCP server receives a Client Link-Layer Address option
   anywhere in any encapsulated message that is not a Relay-Forward DHCP
   message, the server MUST silently ignore that option.

   There is no requirement that a server return this option and its data
   in a downstream DHCP message.

Comment 1 Harald Jensås 2023-02-13 12:11:02 UTC
commit f8c77edbdffb8ada7753ea9fa104f0f6da70cfe3
Author: Simon Kelley <simon.uk>
Date:   Thu Jan 10 21:58:18 2019 +0000

    Fix removal of DHCP_CLIENT_MAC options from DHCPv6 relay replies.

diff --git a/src/rfc3315.c b/src/rfc3315.c
index d3c1722..79b2a86 100644
--- a/src/rfc3315.c
+++ b/src/rfc3315.c
@@ -219,21 +219,25 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
       if (opt6_ptr(opt, 0) + opt6_len(opt) > end) 
         return 0;
      
-      int o = new_opt6(opt6_type(opt));
-      if (opt6_type(opt) == OPTION6_RELAY_MSG)
+      /* Don't copy MAC address into reply. */
+      if (opt6_type(opt) != OPTION6_CLIENT_MAC)
        {
-         struct in6_addr align;
-         /* the packet data is unaligned, copy to aligned storage */
-         memcpy(&align, inbuff + 2, IN6ADDRSZ); 
-         state->link_address = &align;
-         /* zero is_unicast since that is now known to refer to the 
-            relayed packet, not the original sent by the client */
-         if (!dhcp6_maybe_relay(state, opt6_ptr(opt, 0), opt6_len(opt), client_addr, 0, now))
-           return 0;
+         int o = new_opt6(opt6_type(opt));
+         if (opt6_type(opt) == OPTION6_RELAY_MSG)
+           {
+             struct in6_addr align;
+             /* the packet data is unaligned, copy to aligned storage */
+             memcpy(&align, inbuff + 2, IN6ADDRSZ); 
+             state->link_address = &align;
+             /* zero is_unicast since that is now known to refer to the 
+                relayed packet, not the original sent by the client */
+             if (!dhcp6_maybe_relay(state, opt6_ptr(opt, 0), opt6_len(opt), client_addr, 0, now))
+               return 0;
+           }
+         else
+           put_opt6(opt6_ptr(opt, 0), opt6_len(opt));
+         end_opt6(o);
        }
-      else if (opt6_type(opt) != OPTION6_CLIENT_MAC)
-       put_opt6(opt6_ptr(opt, 0), opt6_len(opt));
-      end_opt6(o);         
     }

Comment 3 Petr Menšík 2023-02-14 16:09:12 UTC
Commit f8c77ed [1] appeared in 2.81 release, it is already present in RHEL9.

1. https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;h=f8c77edbdffb8ada7753ea9fa104f0f6da70cfe3

Comment 4 Petr Menšík 2023-02-14 16:31:02 UTC
If I understand correctly how I should test it. It wants OPTION6_CLIENT_MAC(79) on incoming relayed message, but it must not contain that option in the response back. It is not needed for end client and must not be broken as it is.

dnsmasq can work as IPv6 relay too, but probably can accept anything it produced as a server. It might be able to reproduce this issue in one of relaying regression test with small modification.

Comment 17 errata-xmlrpc 2023-05-16 08:43:38 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (dnsmasq bug fix and enhancement update), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2023:2929