Skip to content

Support reconfigure #615

Description

@Izorkin

I added following setting to configuration:

define 145 array byte forcerenew_nonce_capable

I send a reconfiguration request through the DHCP server, but there is no response from DHCP client side.

Using tcpdump can see that the requests are coming in, but the DHCP client debug log is currently showing nothing.

Maybe I'm setting it up incorrectly?

Activity

  1. rsmarples commented on May 25, 2026

    @rsmarples
    Member

    dhcpcd doesn't require any explicit setup for this.
    If you don't specify any authentication then dhcpcd will send the DHO_FORCERENEW_NONCE option by default:

    The DHCP server will then send a nonce back in code 90 which dhcpcd will use to authenticate the force renew message from the server.

    You should be able to verify this with tcpdump.

  2. Izorkin commented on May 25, 2026

    @Izorkin
    Author

    On DHCP server I see that Reconfigure key has been received. I give the command "Send configuration", in "Reconfigure status" shows "FORCERENEW sent, awaiting response".

  3. rsmarples commented on May 25, 2026

    @rsmarples
    Member

    So full disclosure, I don't have a DHCP server that supports authentication ..... yet.
    I might add it to dhcpsd to help diagnose any issues.

    Anyway, it should work, but to verify any issues you'll need to email me a tcpdump of the DHCP transactions at the client side.
    tcpdump -s0 -w/tmp/dhcpcd.cap -I eth0 port bootpc should do it - adjust the interface to taste.

    I need to see the DHCP DISCOVER or REBIND with the server OFFER or ACK to this. Then any FORCERENEW sent as well.

  4. ColinMcInnes commented on Jun 15, 2026

    @ColinMcInnes
    Contributor

    @Izorkin what vendor of DHCP server are you using?

    I have used ISC's older dhcpd and their newer Kea, neither supports forcerenew, so I can't help diagnose this at the moment.

  5. tralalerotralala-orcareloorcala commented on Jul 6, 2026

    @tralalerotralala-orcareloorcala

    dhcpcd/src/dhcp.c

    Line 3154 in 243ad84

    if (state->xid != ntohl(bootp->xid)) {

    Seems like this line always rejects forcerenew messages. It only makes sense to check xid for response mesages, not forcerenew.

  6. rsmarples commented on Jul 7, 2026

    @rsmarples
    Member

    dhcpcd/src/dhcp.c

    Line 3154 in 243ad84

    if (state->xid != ntohl(bootp->xid)) {
    Seems like this line always rejects forcerenew messages. It only makes sense to check xid for response mesages, not forcerenew.

    I think that line is fine. What we probably want to do is change the similar check in dhcp_redirect_dhcp() here:

    dhcpcd/src/dhcp.c

    Line 3097 in 243ad84

    if (state->xid != xid)

    Because FORCERENEW happens over IP we do want to consider multi-homed interacts where you have different leases for the same subnet on different interfaces and may wish to add a test to check authentication for each interface to find a match that way.

  7. tralalerotralala-orcareloorcala commented on Jul 7, 2026

    @tralalerotralala-orcareloorcala

    Maybe. The point was that for incoming FORCERENEW messages the program shouldn't be checking xid at all.

    It seems both checks should be changed, since dhcp_redirect_dhcp calls dhcp_handledhcp again.

  8. Izorkin commented on Jul 22, 2026

    @Izorkin
    Author

    what vendor of DHCP server are you using?

    Use RouterOS v7.23.

  9. ColinMcInnes commented on Jul 22, 2026

    @ColinMcInnes
    Contributor

    what vendor of DHCP server are you using?

    Use RouterOS v7.23.

    Thanks

  10. perkelix commented on Aug 23, 2026

    @perkelix
    Contributor

    Does the above still apply to 10.5.2?

  11. ColinMcInnes commented on Sep 1, 2026

    @ColinMcInnes
    Contributor

    Here's a capture from stock 10.5.2 with MikroTik 7.21. dhcp server is setup with RADIUS.

    Generic config from the build.

    5 packets

    • DISCOVER
    • OFFER
    • REQUEST
    • ACK
    • FORCERENEW

    Then I sent a reconfigure, server says "FORCERENEW sent, waiting for response"

    dump.zip

    Does not log the incoming reconfigure.

    colinmc@colinmc-VirtualBox:~/Downloads/github/dhcpcd$ sudo tail -f /var/log/syslog | grep dhcp
    Sep  1 06:22:52 colinmc-VirtualBox dhcpcd[11888]: received SIGINT, stopping
    Sep  1 06:22:52 colinmc-VirtualBox dhcpcd[11888]: enp0s3: removing interface
    Sep  1 06:22:52 colinmc-VirtualBox dhcpcd[11888]: enp0s3: executing: /libexec/dhcpcd-run-hooks STOPPED
    Sep  1 06:22:52 colinmc-VirtualBox dhcpcd[11888]: dev: unloaded udev
    Sep  1 06:22:52 colinmc-VirtualBox dhcpcd[11888]: dhcpcd exited
    Sep  1 06:22:59 colinmc-VirtualBox dhcpcd[12859]: refusing chroot: dhcpcd: /var/empty
    Sep  1 06:22:59 colinmc-VirtualBox dhcpcd[12859]: dhcpcd-10.5.2 starting
    Sep  1 06:22:59 colinmc-VirtualBox dhcpcd[12859]: udev: starting
    Sep  1 06:22:59 colinmc-VirtualBox dhcpcd[12859]: dev: loaded udev
    Sep  1 06:22:59 colinmc-VirtualBox dhcpcd[12859]: DUID 00:01:00:01:32:29:79:44:08:00:27:a0:95:5e
    Sep  1 06:22:59 colinmc-VirtualBox dhcpcd[12859]: lo: ignoring due to interface type and no config
    Sep  1 06:22:59 colinmc-VirtualBox dhcpcd[12859]: enp0s3: executing: /libexec/dhcpcd-run-hooks PREINIT
    Sep  1 06:22:59 colinmc-VirtualBox dhcpcd[12859]: enp0s3: executing: /libexec/dhcpcd-run-hooks CARRIER
    Sep  1 06:22:59 colinmc-VirtualBox dhcpcd[12859]: enp0s3: IAID 27:a0:95:5e
    Sep  1 06:22:59 colinmc-VirtualBox dhcpcd[12859]: enp0s3: delaying IPv6 router solicitation for 0.1 seconds
    Sep  1 06:22:59 colinmc-VirtualBox dhcpcd[12859]: enp0s3: delaying IPv4 for 1.8 seconds
    Sep  1 06:22:59 colinmc-VirtualBox dhcpcd[12859]: enp0s3: soliciting an IPv6 router
    Sep  1 06:22:59 colinmc-VirtualBox dhcpcd[12859]: enp0s3: sending Router Solicitation
    Sep  1 06:23:01 colinmc-VirtualBox dhcpcd[12859]: enp0s3: reading lease: /var/db/dhcpcd/enp0s3.lease
    Sep  1 06:23:01 colinmc-VirtualBox dhcpcd[12859]: enp0s3: soliciting a DHCP lease
    Sep  1 06:23:01 colinmc-VirtualBox dhcpcd[12859]: enp0s3: sending DISCOVER (xid 0x535aee88), next in 4.4 seconds
    Sep  1 06:23:01 colinmc-VirtualBox dhcpcd[12859]: enp0s3: offered 192.168.88.39 from 192.168.88.1
    Sep  1 06:23:01 colinmc-VirtualBox dhcpcd[12859]: enp0s3: sending REQUEST (xid 0x535aee88), next in 4.9 seconds
    Sep  1 06:23:01 colinmc-VirtualBox dhcpcd[12859]: enp0s3: accepted reconfigure key
    Sep  1 06:23:01 colinmc-VirtualBox dhcpcd[12859]: enp0s3: acknowledged 192.168.88.39 from 192.168.88.1
    Sep  1 06:23:01 colinmc-VirtualBox dhcpcd[12859]: enp0s3: leased 192.168.88.39 for 1800 seconds
    Sep  1 06:23:01 colinmc-VirtualBox dhcpcd[12859]: enp0s3: renew in 900 seconds, rebind in 1575 seconds
    Sep  1 06:23:01 colinmc-VirtualBox dhcpcd[12859]: enp0s3: writing lease: /var/db/dhcpcd/enp0s3.lease
    Sep  1 06:23:01 colinmc-VirtualBox dhcpcd[12859]: enp0s3: adding IP address 192.168.88.39/24 broadcast 192.168.88.255
    Sep  1 06:23:01 colinmc-VirtualBox dhcpcd[12859]: enp0s3: adding route to 192.168.88.0/24
    Sep  1 06:23:01 colinmc-VirtualBox dhcpcd[12859]: enp0s3: adding default route via 192.168.88.1
    Sep  1 06:23:01 colinmc-VirtualBox dhcpcd[12859]: enp0s3: executing: /libexec/dhcpcd-run-hooks BOUND
    Sep  1 06:23:01 colinmc-VirtualBox dhcpcd[12859]: enp0s3: accepted reconfigure key
    Sep  1 06:23:01 colinmc-VirtualBox dhcpcd[12859]: enp0s3: bound, ignoring 192.168.88.39 from 192.168.88.1
    Sep  1 06:23:03 colinmc-VirtualBox dhcpcd[12859]: enp0s3: sending Router Solicitation
    Sep  1 06:23:11 colinmc-VirtualBox dhcpcd[12859]: message repeated 2 times: [ enp0s3: sending Router Solicitation]
    Sep  1 06:23:11 colinmc-VirtualBox dhcpcd[12859]: enp0s3: no IPv6 Routers available
    
  12. ColinMcInnes commented on Sep 1, 2026

    @ColinMcInnes
    Contributor

    Looks like MikroTik is sending xid = 0, which seems like a bug on their side. Maybe they're relying on the client to reject it at the auth state, since forcerenew without auth is considered a huge security loophole.

    Couple of choices then. File a bug with MikroTik to fix their dhcp server, or soft-accept xid 0, but only for forcerenew so it moves on to the auth step.

  13. ColinMcInnes commented on Sep 1, 2026

    @ColinMcInnes
    Contributor

    This lets the renew through

    diff --git a/src/dhcp.c b/src/dhcp.c
    index 078f6927..ff9e5036 100644
    --- a/src/dhcp.c
    +++ b/src/dhcp.c
    @@ -3128,15 +3128,33 @@ dhcp_handledhcp(struct interface *ifp, struct bootp *bootp, size_t bootp_len,
                    return;
            }
     
    -       if (state->xid != ntohl(bootp->xid)) {
    -               if (IS_STATE_ACTIVE(state))
    -                       logdebugx("%s: wrong xid 0x%x (expecting 0x%x) from %s",
    -                           ifp->name, ntohl(bootp->xid), state->xid,
    -                           inet_ntoa(*from));
    -               dhcp_redirect_dhcp(ifp, bootp, bootp_len, from);
    +       /* We may have found a BOOTP server */
    +       if (get_option_uint8(ifp->ctx, &type, bootp, bootp_len,
    +               DHO_MESSAGETYPE) == -1)
    +               type = 0;
    +       else if (ifo->options & DHCPCD_BOOTP) {
    +               logdebugx("%s: ignoring DHCP reply (expecting BOOTP)",
    +                   ifp->name);
                    return;
            }
     
    +       if (state->xid != ntohl(bootp->xid)) {
    +               /* If the xid is 0 in a BOOTP reply FORCERENEW, move on and check AUTH
    +                  MikroTik dhpc servers send xid 0*/
    +               if (bootp->xid == 0 && type == DHCP_FORCERENEW) {
    +                       if (IS_STATE_ACTIVE(state))
    +                               logdebugx("%s: Received xid 0 in a BOOTP reply FORCERENEW from %s, moving on to check AUTH",
    +                                       ifp->name, inet_ntoa(*from));
    +               } else {
    +                       if (IS_STATE_ACTIVE(state))
    +                               logdebugx("%s: wrong xid 0x%x (expecting 0x%x) from %s",
    +                                       ifp->name, ntohl(bootp->xid), state->xid,
    +                                       inet_ntoa(*from));
    +                       dhcp_redirect_dhcp(ifp, bootp, bootp_len, from);
    +                       return;
    +               }
    +       }
    +
            if (ifp->hwlen <= sizeof(bootp->chaddr) &&
                memcmp(bootp->chaddr, ifp->hwaddr, ifp->hwlen)) {
                    if (IS_STATE_ACTIVE(state)) {
    @@ -3170,16 +3188,6 @@ dhcp_handledhcp(struct interface *ifp, struct bootp *bootp, size_t bootp_len,
                    }
            }
     
    -       /* We may have found a BOOTP server */
    -       if (get_option_uint8(ifp->ctx, &type, bootp, bootp_len,
    -               DHO_MESSAGETYPE) == -1)
    -               type = 0;
    -       else if (ifo->options & DHCPCD_BOOTP) {
    -               logdebugx("%s: ignoring DHCP reply (expecting BOOTP)",
    -                   ifp->name);
    -               return;
    -       }
    -
     #ifdef AUTH
            /* Authenticate the message */
            auth = get_option(ifp->ctx, bootp, bootp_len, DHO_AUTHENTICATION,
    
    
  14. Izorkin commented on Sep 2, 2026

    @Izorkin
    Author

    @ColinMcInnes thanks.
    If restart the dhcpcd service, IP address renewal will not work initially. Forced renewal will only work after the first lease renewal.

  15. ColinMcInnes commented on Sep 2, 2026

    @ColinMcInnes
    Contributor

    @ColinMcInnes thanks. If restart the dhcpcd service, IP address renewal will not work initially. Forced renewal will only work after the first lease renewal.

    What about the change in #719? Does the initial renewal fail there too?

    I can setup my MikroTik test again, it occurred to me I hadn't checked regular renewal, just whether force renewal was getting through.

  16. Izorkin commented on Sep 2, 2026

    @Izorkin
    Author

    What about the change in #719? Does the initial renewal fail there too?

    I tested this patch. It only works occasionally.

  17. ColinMcInnes commented on Sep 2, 2026

    @ColinMcInnes
    Contributor

    I tested this patch. It only works occasionally.

    Only the occasional renewal? Interesting. I might need to setup a longer term monitoring.

    Did it spit out any logs saying it was rejecting the renewals for any reason?

  18. ColinMcInnes commented on Sep 7, 2026

    @ColinMcInnes
    Contributor

    @Izorkin I'm unable to replicate your issue with #719. I have Mikrotik set to 5 minute renewals, and I can both trigger force renew from the server, but it also renews all by itself, even the initial renewal. I can even force a renew right after it is initially bound, and it will renew itself after a reconfigure when the renew timer expires.

    When you replicate the initial renewal fail, can you please post some logs?

    One thing I did notice though is that when it's in BOUND state, all the auth info is printed out with the lease dump (replay, info, protocol, etc). But when it's in RENEW state, it only prints out if it's nonce capable. @rsmarples Is that a bug?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions