[Dnsmasq-discuss] [PATCH] Add DHCP6REPLY for DHCP6REBIND

Simon Kelley simon at thekelleys.org.uk
Thu Apr 8 22:37:47 UTC 2021


On 08/04/2021 10:16, Aichun Li wrote:
> From: liaichun <liaichun at huawei.com>
> 
> Before this, we receive a DHCP6REBIND request and do not reply.
> We should increase the number of responses to such packets.
> 

Not good to have omitted this for so long. Thanks for the patch.

Since most of the code is the same for DHCPRENEW and DHCPREBIND, I
prefer to share it. Also,  reading RFC8415 18.3.5, if no lease exists or
can be created for any of the IAs, there should be an error status of no
addresses available in the reply.

The attached patch make these changes. Please could you check that it
works OK for you?


Cheers,

Simon.

-------------- next part --------------
diff --git a/src/rfc3315.c b/src/rfc3315.c
index 982c68a..5c2ff97 100644
--- a/src/rfc3315.c
+++ b/src/rfc3315.c
@@ -919,11 +919,14 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
       
   
     case DHCP6RENEW:
+    case DHCP6REBIND:
       {
+	int address_assigned = 0;
+
 	/* set reply message type */
 	*outmsgtypep = DHCP6REPLY;
 	
-	log6_quiet(state, "DHCPRENEW", NULL, NULL);
+	log6_quiet(state, msg_type == DHCP6RENEW ? "DHCPRENEW" : "DHCPREBIND", NULL, NULL);
 
 	for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
 	  {
@@ -952,24 +955,35 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
 					  state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, 
 					  state->iaid, &req_addr)))
 		  {
-		    /* If the server cannot find a client entry for the IA the server
-		       returns the IA containing no addresses with a Status Code option set
-		       to NoBinding in the Reply message. */
-		    save_counter(iacntr);
-		    t1cntr = 0;
-		    
-		    log6_packet(state, "DHCPREPLY", &req_addr, _("lease not found"));
-		    
-		    o1 = new_opt6(OPTION6_STATUS_CODE);
-		    put_opt6_short(DHCP6NOBINDING);
-		    put_opt6_string(_("no binding found"));
-		    end_opt6(o1);
-
-		    preferred_time = valid_time = 0;
-		    break;
+		    if (msg_type == DHCP6REBIND)
+		      {
+			/* When rebinding, we can create a lease if it doesn't exist. */
+			lease = lease6_allocate(&req_addr, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA);
+			if (lease)
+			  lease_set_iaid(lease, state->iaid);
+			else
+			  break;
+		      }
+		    else
+		      {
+			/* If the server cannot find a client entry for the IA the server
+			   returns the IA containing no addresses with a Status Code option set
+			   to NoBinding in the Reply message. */
+			save_counter(iacntr);
+			t1cntr = 0;
+			
+			log6_packet(state, "DHCPREPLY", &req_addr, _("lease not found"));
+			
+			o1 = new_opt6(OPTION6_STATUS_CODE);
+			put_opt6_short(DHCP6NOBINDING);
+			put_opt6_string(_("no binding found"));
+			end_opt6(o1);
+			
+			preferred_time = valid_time = 0;
+			break;
+		      }
 		  }
 		
-		
 		if ((this_context = address6_available(state->context, &req_addr, tagif, 1)) ||
 		    (this_context = address6_valid(state->context, &req_addr, tagif, 1)))
 		  {
@@ -1000,6 +1014,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
 		    
 		    if (preferred_time == 0)
 		      message = _("deprecated");
+
+		    address_assigned = 1;
 		  }
 		else
 		  {
@@ -1022,10 +1038,18 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
 	    end_ia(t1cntr, min_time, 1);
 	    end_opt6(o);
 	  }
+
+	if (!address_assigned && msg_type == DHCP6REBIND)
+	  { 
+	    /* can't create lease for any address, return error */
+	    o1 = new_opt6(OPTION6_STATUS_CODE);
+	    put_opt6_short(DHCP6NOADDRS);
+	    put_opt6_string(_("no addresses available"));
+	    end_opt6(o1);
+	  }
 	
 	tagif = add_options(state, 0);
 	break;
-	
       }
       
     case DHCP6CONFIRM:


More information about the Dnsmasq-discuss mailing list