My current ISP announces two prefixes through ICMPv6 RAs. Both of them have different prefixes announced through ND_OPT_PREFIX_INFORMATION ( https://www.ietf.org/rfc/rfc3542.txt ), which is fine, as odhcp6c will store these in separate entries.
However, they also have different reachable times announced through nd_router_advert.nd_ra_reachable ( https://www.ietf.org/rfc/rfc3542.txt ) and odhcp6c stores these in a single global variable (ra_reachable). Since my ISP sends these ICMPv6 every three seconds and one overrides the other, ra_holdoff is ignored and the dhcpv6.script is called twice every 3 seconds, causing a significant saturation on my weak TP-Link Archer C6 v2 (US) CPU.
I understand the solution above is very hacky and not a proper one, but I am not a DHCPv6 expert and it's hopeless to contact my ISP and ask them to fix their configuration.
Posting this in the hopes that more knowledgeable DHCPv6 developers can come up with a better solution.
On top of the problem described in the OP, my ISP, in their infinite wisdom, has decided to break IPv6 by dropping all packets at my edge gateway, if their source addresses come from prefixes announced through Router Advertisements.
This not only broke odhcp6c, but also my Linux and Windows desktop PCs lost IPv6 connectivity by using one of the RA addresses as the system-wide default IPv6 address (this happens when they are connected directly to the bridged cable modem).
Trying to get my ISP to fix this is a waste of time; it's either automated "tech" support or stupid telemarketing types that don't even know what IPv6 is.
For the time being, as a dirty fix that "solves" both issues, I've removed router-advertisement from the list of accepted ICMPv6 types in the Allow-ICMPv6-Input traffic rule. IPv6 address and prefix is obtained solely by a explicit request from odhcp6c (configuration options reqaddress and reqprefix).
If you are from Brazil and is reading this, STAY AWAY from Claro/NET, you will thank me later.