1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-17 04:52:59 +01:00

Merge pull request #16724 from JKRhb/dhcp-ia-na-refactor

sys/net/dhcpv6: Refactor IA_NA implementation
This commit is contained in:
Martine Lenders 2021-08-12 16:52:50 +02:00 committed by GitHub
commit 170af29917
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 129 deletions

View File

@ -204,6 +204,20 @@ void dhcpv6_client_conf_prefix(unsigned netif, const ipv6_addr_t *pfx,
unsigned pfx_len, uint32_t valid,
uint32_t pref);
/**
* @brief Configures a address lease that is provided by the server.
*
* @param[in] netif Network interface the address was for.
* @param[in] addr The assigned address.
* @param[in] valid Valid lifetime of the address.
* @param[in] pref Preferred lifetime of the address.
*/
static inline void dhcpv6_client_conf_addr(unsigned netif, const ipv6_addr_t *addr,
uint32_t valid, uint32_t pref)
{
dhcpv6_client_conf_prefix(netif, addr, IPV6_ADDR_BIT_LEN, valid, pref);
}
/**
* @brief Checks if the given network interface is configured
* to use DHCPv6 IA_NA
@ -214,33 +228,6 @@ void dhcpv6_client_conf_prefix(unsigned netif, const ipv6_addr_t *pfx,
*/
bool dhcpv6_client_check_ia_na(unsigned netif);
/**
* @brief Configures a address lease that is provided by the server.
*
* @param[in] netif Network interface the address was for.
* @param[in] addr The assigned address.
*
* @return sizeof(ipv6_addr_t) on success.
* @return <0 on error.
*/
int dhcpv6_client_add_addr(unsigned netif, ipv6_addr_t *addr);
/**
* @brief Deprecates an existing address from an address lease.
*
* @param[in] netif Network interface the address was for.
* @param[in] addr The address to deprecate.
*/
void dhcpv6_client_deprecate_addr(unsigned netif, const ipv6_addr_t *addr);
/**
* @brief Removes an existing address that originated from an address lease.
*
* @param[in] netif Network interface the address was for.
* @param[in] addr The address to remove.
*/
void dhcpv6_client_remove_addr(unsigned netif, ipv6_addr_t *addr);
/**
* @brief Determines how long the prefix delegation lease is still valid.
*
@ -253,6 +240,21 @@ void dhcpv6_client_remove_addr(unsigned netif, ipv6_addr_t *addr);
uint32_t dhcpv6_client_prefix_valid_until(unsigned netif,
const ipv6_addr_t *pfx,
unsigned pfx_len);
/**
* @brief Determines how long the address lease is still valid.
*
* @param[in] netif Network interface the address was for.
* @param[in] addr The assigned address.
*
* @return Remaining valid lifetime of the address lease in seconds.
*/
static inline uint32_t dhcpv6_client_addr_valid_until(unsigned netif,
const ipv6_addr_t *addr)
{
return dhcpv6_client_prefix_valid_until(netif, addr, IPV6_ADDR_BIT_LEN);
}
/** @} */
/**

View File

@ -69,8 +69,6 @@ typedef struct {
lease_t parent;
ipv6_addr_t addr;
uint8_t leased;
uint32_t valid_until;
uint32_t pref_until;
} addr_lease_t;
/**
@ -90,8 +88,7 @@ static uint8_t duid[DHCPV6_CLIENT_DUID_LEN];
static addr_lease_t addr_leases[CONFIG_DHCPV6_CLIENT_ADDR_LEASE_MAX];
static pfx_lease_t pfx_leases[CONFIG_DHCPV6_CLIENT_PFX_LEASE_MAX];
static server_t server;
static event_timeout_t solicit_renew_timeout, rebind_timeout,
deprecate_remove_timeout;
static event_timeout_t solicit_renew_timeout, rebind_timeout;
static event_queue_t *event_queue;
static sock_udp_t sock;
static sock_udp_ep_t local = { .family = AF_INET6, .port = DHCPV6_CLIENT_PORT };
@ -112,7 +109,6 @@ static void _solicit_servers(event_t *event);
static void _request(event_t *event);
static void _renew(event_t *event);
static void _rebind(event_t *event);
static void _deprecate_remove_addrs(event_t *event);
static void _set_event_timeout_ms(event_timeout_t *timeout, event_t *event,
uint32_t delay_ms);
@ -124,7 +120,6 @@ static event_t solicit_servers = { .handler = _solicit_servers };
static event_t request = { .handler = _request };
static event_t renew = { .handler = _renew };
static event_t rebind = { .handler = _rebind };
static event_t deprecate_remove_addrs = { .handler = _deprecate_remove_addrs };
#ifdef MODULE_AUTO_INIT_DHCPV6_CLIENT
static char _thread_stack[DHCPV6_CLIENT_STACK_SIZE];
@ -681,15 +676,10 @@ static void _update_addr_lease(const dhcpv6_opt_iaaddr_t *iaaddr, addr_lease_t *
lease->leased = 1U;
memcpy(&lease->addr, &iaaddr->addr, sizeof(ipv6_addr_t));
if (dhcpv6_client_add_addr(lease->parent.ia_id.info.netif,
&lease->addr) == sizeof(ipv6_addr_t)) {
DEBUG("IP ADDRESS successfully added!\n");
lease->pref_until = pref;
lease->valid_until = valid;
_set_event_timeout_sec(&deprecate_remove_timeout, &deprecate_remove_addrs,
pref);
}
dhcpv6_client_conf_addr(
lease->parent.ia_id.info.netif, &lease->addr,
valid, pref
);
}
}
@ -1135,7 +1125,9 @@ static void _request_renew_rebind(uint8_t type)
(i < CONFIG_DHCPV6_CLIENT_ADDR_LEASE_MAX);
i++) {
const addr_lease_t *lease = &addr_leases[i];
uint32_t valid_until = lease->valid_until;
uint32_t valid_until = dhcpv6_client_addr_valid_until(
lease->parent.ia_id.info.netif, &lease->addr
);
if (valid_until > mrd) {
mrd = valid_until;
}
@ -1218,33 +1210,6 @@ static void _rebind(event_t *event)
_request_renew_rebind(DHCPV6_REBIND);
}
static void _deprecate_remove_addrs(event_t *event)
{
if (!IS_USED(MODULE_DHCPV6_CLIENT_IA_NA)) {
return;
}
(void)event;
for (unsigned i = 0; (i < CONFIG_DHCPV6_CLIENT_ADDR_LEASE_MAX); i++) {
uint32_t now = _now_sec();
addr_lease_t *lease = &addr_leases[i];
if (now >= lease->valid_until) {
DEBUG("DHCPv6 client: removing address\n");
dhcpv6_client_remove_addr(lease->parent.ia_id.info.netif,
&lease->addr);
lease->leased = 0U;
} else if (now >= lease->pref_until) {
DEBUG("DHCPv6 client: deprecating address\n");
dhcpv6_client_deprecate_addr(lease->parent.ia_id.info.netif,
&lease->addr);
_set_event_timeout_sec(&deprecate_remove_timeout,
&deprecate_remove_addrs,
lease->valid_until);
}
}
}
static void _set_event_timeout_ms(event_timeout_t *timeout, event_t *event,
uint32_t delay_ms)
{

View File

@ -96,36 +96,6 @@ bool dhcpv6_client_check_ia_na(unsigned iface)
return netif->ipv6.aac_mode & GNRC_NETIF_AAC_DHCP;
}
int dhcpv6_client_add_addr(unsigned iface, ipv6_addr_t *addr)
{
gnrc_netif_t *netif = gnrc_netif_get_by_pid(iface);
DEBUG("DHCPv6 client: ADD IP ADDRESS\n");
return gnrc_netif_ipv6_addr_add(netif, addr, 64, 0);
}
void dhcpv6_client_deprecate_addr(unsigned iface, const ipv6_addr_t *addr)
{
gnrc_netif_t *netif = gnrc_netif_get_by_pid(iface);
int i;
gnrc_netif_acquire(netif);
i = gnrc_netif_ipv6_addr_idx(netif, addr);
if (i >= 0) {
netif->ipv6.addrs_flags[i] &= ~GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_MASK;
netif->ipv6.addrs_flags[i] |= GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_DEPRECATED;
}
gnrc_netif_release(netif);
}
void dhcpv6_client_remove_addr(unsigned iface, ipv6_addr_t *addr)
{
gnrc_netif_t *netif = gnrc_netif_get_by_pid(iface);
gnrc_netif_ipv6_addr_remove(netif, addr);
}
uint32_t dhcpv6_client_prefix_valid_until(unsigned netif,
const ipv6_addr_t *pfx,
unsigned pfx_len)

View File

@ -15,6 +15,7 @@ from ipaddress import (
IA_NA_ADDRESS_POOL_PREFIX = "2001:db8:1::"
IA_PD_PREFIX = "2001:db8:8000::"
def testfunc(child):
@ -23,17 +24,26 @@ def testfunc(child):
child.expect(r"Iface\s+\d+")
child.expect(r"inet6 addr:\s+fe80:[0-9a-f:]+\s+scope: link")
global_addr_1, global_addr_2 = extract_global_addresses(child)
global_addr_1 = extract_global_address(child)
global_addr_2 = extract_global_address(child)
assert global_addr_1 != global_addr_2
global_pfx = extract_global_prefix(child)
global_pfx_1 = extract_global_prefix(child)
global_pfx_2 = extract_global_prefix(child)
assert global_pfx_1 != global_pfx_2
test_global_addrs(global_addr_1, global_addr_2, global_pfx)
assert check_ia_na_addr(global_addr_1, global_pfx_1) or \
check_ia_pd_addr(global_addr_1, global_pfx_1)
assert check_ia_na_addr(global_addr_2, global_pfx_2) or \
check_ia_pd_addr(global_addr_2, global_pfx_2)
def extract_global_prefix(child):
child.expect(r"(?P<global_pfx>[0-9a-f:]+)/64\s+dev #\d\s+"
r"expires \d+ sec\s+"
r"deprecates \d+ sec")
child.expect(
r"(?P<global_pfx>[0-9a-f:]+)\/(64|128)\s+dev #\d\s+"
r"expires \d+ sec\s+"
r"deprecates \d+ sec"
)
global_pfx = child.match.group("global_pfx")
if global_pfx.endswith("::"):
@ -50,36 +60,22 @@ def extract_global_address(child):
return child.match.group("global_addr")
def extract_global_addresses(child):
"""Extract two global addresses and return them as a tuple."""
return extract_global_address(child), extract_global_address(child)
def check_prefix(addr, prefix):
return addr.startswith(prefix)
def check_ia_na_addr(ia_na_addr):
def check_ia_na_addr(ia_na_addr, global_pfx):
"""Check if the expected IA_NA address has been assigned"""
return IPv6Address(ia_na_addr) in IPv6Network("{}/64".format(IA_NA_ADDRESS_POOL_PREFIX))
result = IPv6Address(ia_na_addr) in IPv6Network(f"{IA_NA_ADDRESS_POOL_PREFIX}/64")
result = result and check_prefix(ia_na_addr, global_pfx)
return result
def check_ia_pd_addr(ia_pd_addr, global_pfx):
"""Check if the expected IA_PD address has been assigned"""
return ia_pd_addr.startswith(global_pfx)
def check_global_addrs(ia_na_addr, ia_pd_addr, global_pfx):
"""Perform IA_NA check for the first and IA_PD for the second address"""
return {
"ia_na_check": check_ia_na_addr(ia_na_addr),
"ia_pd_check": check_ia_pd_addr(ia_pd_addr, global_pfx),
}
def test_global_addrs(global_addr_1, global_addr_2, global_pfx):
"""Assert that one global address is the IA_NA and the other one is the IA_PD address"""
result_1 = check_global_addrs(global_addr_1, global_addr_2, global_pfx)
result_2 = check_global_addrs(global_addr_2, global_addr_1, global_pfx)
assert result_1 != result_2
assert result_1["ia_na_check"] != result_2["ia_na_check"]
assert result_1["ia_pd_check"] != result_2["ia_pd_check"]
result = IPv6Address(ia_pd_addr) in IPv6Network(f"{IA_PD_PREFIX}/33")
result = result and check_prefix(ia_pd_addr, global_pfx)
return result
if __name__ == "__main__":