Bug 377101 - TAHI--DHCPv6--DUID cannot be kept consistent
Summary: TAHI--DHCPv6--DUID cannot be kept consistent
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 5
Classification: Red Hat
Component: dhcpv6
Version: 5.0
Hardware: All
OS: Linux
urgent
medium
Target Milestone: rc
: ---
Assignee: David Cantrell
QA Contact:
URL:
Whiteboard:
: 436870 (view as bug list)
Depends On:
Blocks: 253764 462692
TreeView+ depends on / blocked
 
Reported: 2007-11-12 05:55 UTC by Zhiyong Wu
Modified: 2023-02-08 01:12 UTC (History)
4 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2009-01-20 21:38:22 UTC
Target Upstream Version:
Embargoed:
ryang: needinfo+


Attachments (Terms of Use)
dhcpv6-1.0.4-bz377101.patch (5.09 KB, patch)
2008-01-11 23:09 UTC, David Cantrell
no flags Details | Diff
dhcpv6-1.0.4-bz377101.patch (4.28 KB, patch)
2008-01-11 23:12 UTC, David Cantrell
no flags Details | Diff
dhcpv6-1.0.10-duid_match_llt.patch (1.76 KB, patch)
2008-10-07 23:44 UTC, David Cantrell
no flags Details | Diff


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2009:0165 0 normal SHIPPED_LIVE dhcpv6 bug fix update 2009-01-20 16:05:26 UTC

Description Zhiyong Wu 2007-11-12 05:55:34 UTC
Description of problem:

  When having dhcpv6 tests for rfc3315 in the host mode,we found that DUID 

cannot be kept consistent in some scenarios.

Version-Release number of selected component (if applicable):

  kernel-2.6.18-43.el5

Software Environment:   
  Testee(NUT):   
    RHEL5 
    Kernel:2.6.18-43.el5 
   
  Tester(TN):   
    FreeBSD6.2
    v6eval-3.0.12.tar.gz
   
TAHI package:    
  DHCPv6_Self_Test_P2_1_0_7.tar.gz

How reproducible:
  every time

Steps to Reproduce:    
  1. Configure TAHI test environment.     
  2. Run the TAHI test suite     
  3. After the test completes, check for the results 
  
Actual results:

   DUID cannot be kept consistent. 

Expected results:

   DUID should be kept consistent.

Additional info:
  
   please refer to

http://focus.brisbane.redhat.com/~zwu/dhcp_client/20071030/DHCPv6_Self_Test_P2_1_0_7_client/rfc3315/index.html

   (1)17	Part B : DUID-LLT Consistency

Comment 1 RHEL Program Management 2007-11-15 08:54:24 UTC
This request was evaluated by Red Hat Product Management for inclusion in a Red
Hat Enterprise Linux maintenance release.  Product Management has requested
further review of this request by Red Hat Engineering, for potential
inclusion in a Red Hat Enterprise Linux Update release for currently deployed
products.  This request is not yet committed for inclusion in an Update
release.

Comment 2 David Cantrell 2008-01-11 23:08:50 UTC
dhcp6c was saving the DUID when one was initially generated, but not any on
received messages.  I have patched the code so that the received DUID-LLT is
saved to the DUID_FILE in /var/lib, which should maintain a consistent DUID
across reboots.

Attaching the patch to this bug report.

Comment 3 David Cantrell 2008-01-11 23:09:16 UTC
Created attachment 291437 [details]
dhcpv6-1.0.4-bz377101.patch

Comment 4 David Cantrell 2008-01-11 23:11:14 UTC
Comment on attachment 291437 [details]
dhcpv6-1.0.4-bz377101.patch

>diff --git a/include/common.h b/include/common.h
>index 3058596..ba1937c 100644
>--- a/include/common.h
>+++ b/include/common.h
>@@ -80,6 +80,8 @@ extern void dprintf __P((int, const char *, ...));
> #endif
> 
> extern int get_duid __P((const char *, const char *, struct duid *));
>+extern int save_duid __P((const char *, const char *, struct duid *));
>+extern u_int16_t calculate_duid_len __P((const char *));
> extern void dhcp6_init_options __P((struct dhcp6_optinfo *));
> extern void dhcp6_clear_options __P((struct dhcp6_optinfo *));
> extern int dhcp6_copy_options __P((struct dhcp6_optinfo *,
>diff --git a/src/common.c b/src/common.c
>index 858ac70..913b0a1 100644
>--- a/src/common.c
>+++ b/src/common.c
>@@ -721,14 +721,7 @@ get_duid(const 	char *idfile, const char *ifname,
> 			goto fail;
> 		}
> 	} else {
>-		int l;
>-
>-		if ((l = gethwid(tmpbuf, sizeof(tmpbuf), ifname, &hwtype)) < 0) {
>-			dprintf(LOG_INFO, "%s"
>-			    "failed to get a hardware address", FNAME);
>-			goto fail;
>-		}
>-		len = l + sizeof(struct dhcp6_duid_type1);
>+		len = calculate_duid_len(ifname);
> 	}
> 
> 	memset(duid, 0, sizeof(*duid));
>@@ -763,29 +756,57 @@ get_duid(const 	char *idfile, const char *ifname,
> 			duidstr(duid));
> 	}
> 
>+	/* save DUID */
>+	if (save_duid(idfile, ifname, duid)) {
>+		dprintf(LOG_DEBUG, "%s" "failed to save DUID: %s", FNAME,
>+			duidstr(duid));
>+		goto fail;
>+	}
>+
>+	if (fp)
>+		fclose(fp);
>+	return (0);
>+
>+fail:
>+	if (fp)
>+		fclose(fp);
>+	if (duid->duid_id != NULL) {
>+		duidfree(duid);
>+	}
>+	return (-1);
>+}
>+
>+int
>+save_duid(const char *idfile, const char *ifname, struct duid *duid)
>+{
>+	FILE *fp = NULL;
>+	u_int16_t len = 0;
>+
>+	/* calculate DUID length */
>+	len = calculate_duid_len(ifname);
>+
> 	/* save the (new) ID to the file for next time */
> #ifdef LIBDHCP
> 	if (libdhcp_control && (libdhcp_control->capability & DHCP_USE_LEASE_DATABASE))
> #endif
>-	if (!fp) {
>-		if ((fp = fopen(idfile, "w+")) == NULL) {
>-			dprintf(LOG_ERR, "%s"
>-			    "failed to open DUID file for save", FNAME);
>-			goto fail;
>-		}
>-		if ((fwrite(&len, sizeof(len), 1, fp)) != 1) {
>-			dprintf(LOG_ERR, "%s" "failed to save DUID", FNAME);
>-			goto fail;
>-		}
>-		if ((fwrite(duid->duid_id, len, 1, fp)) != 1) {
>-			dprintf(LOG_ERR, "%s" "failed to save DUID", FNAME);
>-			goto fail;
>-		}
>+	if ((fp = fopen(idfile, "w+")) == NULL) {
>+		dprintf(LOG_ERR, "%s"
>+		    "failed to open DUID file for save", FNAME);
>+		goto fail;
>+	}
> 
>-		dprintf(LOG_DEBUG, "%s" "saved generated DUID to %s", FNAME,
>-			idfile);
>+	if ((fwrite(&len, sizeof(len), 1, fp)) != 1) {
>+		dprintf(LOG_ERR, "%s" "failed to save DUID", FNAME);
>+		goto fail;
> 	}
> 
>+	if ((fwrite(duid->duid_id, len, 1, fp)) != 1) {
>+		dprintf(LOG_ERR, "%s" "failed to save DUID", FNAME);
>+		goto fail;
>+	}
>+
>+	dprintf(LOG_DEBUG, "%s" "saved generated DUID to %s", FNAME, idfile);
>+
> 	if (fp)
> 		fclose(fp);
> 	return (0);
>@@ -799,6 +820,24 @@ get_duid(const 	char *idfile, const char *ifname,
> 	return (-1);
> }
> 
>+u_int16_t
>+calculate_duid_len(const char *ifname)
>+{
>+	int l;
>+	u_int16_t ret = 0, hwtype;
>+	struct dhcp6_duid_type1 *dp; /* we only support the type1 DUID */
>+	unsigned char tmpbuf[256];	/* DUID should be no more than 256 bytes */
>+
>+	if ((l = gethwid(tmpbuf, sizeof(tmpbuf), ifname, &hwtype)) < 0) {
>+		dprintf(LOG_INFO, "%s"
>+		    "failed to get a hardware address", FNAME);
>+		return 0;
>+	}
>+
>+	ret = l + sizeof(struct dhcp6_duid_type1);
>+	return ret;
>+}
>+
> ssize_t
> gethwid(buf, len, ifname, hwtypep)
> 	unsigned char *buf;
>diff --git a/src/dhcp6c.c b/src/dhcp6c.c
>index 14e589e..255b161 100644
>--- a/src/dhcp6c.c
>+++ b/src/dhcp6c.c
>@@ -555,6 +555,7 @@ client6_ifinit(char *device)
> 	memcpy(&client6_iaidaddr.client6_info.iaidinfo, &ifp->iaidinfo, 
> 			sizeof(client6_iaidaddr.client6_info.iaidinfo));
> 	duidcpy(&client6_iaidaddr.client6_info.clientid, &client_duid);
>+	save_duid(DUID_FILE, device, &client_duid);
> #ifdef LIBDHCP
> 	if (libdhcp_control && (libdhcp_control->capability & DHCP_USE_LEASE_DATABASE)) {
> #endif
>@@ -1050,6 +1051,12 @@ client6_send(ev)
> 		goto end;
> 	}
> 
>+	/* save DUID now for persistent DUID (e.g., if client reboots) */
>+	if (save_duid(DUID_FILE, device, &client_duid)) {
>+		dprintf(LOG_ERR, "%s" "failed to save client ID", FNAME);
>+		goto end;
>+	}
>+
> 	/* option request options */
> 	if (dhcp6_copy_list(&optinfo.reqopt_list, &ifp->reqopt_list)) {
> 		dprintf(LOG_ERR, "%s" "failed to copy requested options",

Comment 5 David Cantrell 2008-01-11 23:12:03 UTC
Created attachment 291438 [details]
dhcpv6-1.0.4-bz377101.patch

Comment 7 Zhiyong Wu 2008-02-22 07:16:11 UTC
but the test cases FAIL on RHEL5.2 with dhcpv6-1.0.10

for more details, pls refer to

http://focus.brisbane.redhat.com/~zwu/RHEL5.2-Server-20080212.0/20080220/DHCPv6_Self_Test_P2_1_0_8_client_1.0.10/rfc3315/17.html

Comment 9 Denise Dumas 2008-02-27 15:31:52 UTC
In order to debug this problem, we need the test case for RHEL 5.2 with an exact
reproducer, including output with verbose debugging messages from the DHCPV6
software.  One way to do this would be to extract the commands that TAHI runs.
The man pages for dhcp6s, dhcp6r, and dhcp6c all show how to generate verbose
debug messages. 

Comment 11 David Cantrell 2008-03-12 20:16:35 UTC
Fixed in dhcpv6-1.0.10-2.el5.

Comment 13 David Cantrell 2008-03-14 19:54:17 UTC
*** Bug 436870 has been marked as a duplicate of this bug. ***

Comment 18 David Cantrell 2008-06-03 21:02:48 UTC
When the NUT reboots, is the /var/lib/dhcpv6 directory getting cleared out before starting dhcp6c again?  
The DUID is recorded as /var/lib/dhcpv6/dhcp6c_duid, so the only way to keep it persistent is to make 
sure that file isn't removed.  Any time it's removed, a new DUID will be generated by the client.

Comment 19 Red Hat Bugzilla 2008-07-08 01:24:26 UTC
Adding yshao to the cc list as the manager of the disabled user zwu who reported this bug

Comment 20 David Cantrell 2008-07-15 19:27:02 UTC

*** This bug has been marked as a duplicate of 439526 ***

Comment 21 David Cantrell 2008-07-15 23:27:14 UTC
Is this still happening in RHEL 5.2 or the 5.2.z update?  I'm pretty sure all of the instances where the DUID 
needs to be written out are in the code, but I may have missed one.  Please let me know if it's working 5.2 
or 5.2.z.

Thanks.

Comment 22 David Cantrell 2008-07-22 01:47:05 UTC
Any updated info with regards to comment #21?

Thanks.

Comment 23 David Cantrell 2008-09-16 21:06:36 UTC
OK, I think this is related to a similar problem that dhcp6c had earlier.  We weren't saving the generated DUID in dhcp6c, so a call to save_duid() was added.

I've added calls to save_duid() in dhcp6s in the same style as what we did in dhcp6c.  This should solve the consistency between reboots problems.

One thing that's confusing to me is that get_duid() will either read in the saved DUID or generate a new one, then it calls save_duid() to save it.  However, that is what's happening now and the consistency is not there, so something must occur to the DUID during the course of the program running, so we need to save it again.

If this patch doesn't fix things up, my suggestion will be to modify the signal handler in dhcp6s to call save_duid() before exiting to ensure we have the latest copy saved.

The fix will be in dhcpv6-1.0.10-8.el5.

Comment 24 Jiri Skrabal 2008-09-17 12:27:01 UTC
Are we ready to go or is the state still "needinfo"? If no additional information needed, I can approve for 5.2.z.

Thanks

Comment 25 Lawrence Lim 2008-09-17 14:47:57 UTC
Testing.

Trying to get rid of the NEED_INFO since its in MODIFIED state.

Comment 31 David Cantrell 2008-10-07 23:43:09 UTC
Fixed this in dhcpv6-1.0.10-10.el5.  This one has taken me a while.  I retraced everything today and finally figured out what was happening.  I had been looking at the wrong place in the code the entire time.

Once we have the client DUID, the server DUID LLT field is updated so they match.  The rest of the DUID is left untouched.

Watching the communication via wireshark, it looks like this will work for the test (I hope anyway).  Attaching the patch so you can see.  It ended up being pretty simple.

Comment 32 David Cantrell 2008-10-07 23:44:26 UTC
Created attachment 319707 [details]
dhcpv6-1.0.10-duid_match_llt.patch

Comment 35 Lawrence Lim 2008-10-08 00:37:27 UTC
Great! Thanks David. 

llim->ryang: could you please run the test today and let us know the good news? :)

Comment 37 David Cantrell 2008-10-14 01:20:19 UTC
I just retested dhcpv6-1.0.10-10.el5 and with dhcpv6-1.0.10-11.el5 and the DUID LLT values match for the client and server.  I did an information request and a normal IANA exchange and the LLT time value matched the entire time.

The DUID also remained consistent through reboots.

The MAC field of the DUID is different between the client and server, but that is how it should be, right?  The server DUID should have the server MAC address and the client DUID should have the client MAC address, right?  The DUID LLT should match between both of them.

Please retest using dhcpv6-1.0.10-11.el5.  I am showing the LLT TIME values are matched with both dhcpv6-1.0.10-10.el5 and dhcpv6-1.0.10-11.el5.

Comment 46 errata-xmlrpc 2009-01-20 21:38:22 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on therefore solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHBA-2009-0165.html


Note You need to log in before you can comment on or make changes to this bug.