Lines Matching full:dhcpv6
8 * @brief DHCPv6 client implementation
14 #include <zephyr/net/dhcpv6.h>
70 sys_rand_get(iface->config.dhcpv6.tid, sizeof(iface->config.dhcpv6.tid)); in dhcpv6_generate_tid()
129 if (iface->config.dhcpv6.t1 > t1_abs) { in dhcvp6_update_deadlines()
130 iface->config.dhcpv6.t1 = t1_abs; in dhcvp6_update_deadlines()
133 if (iface->config.dhcpv6.t2 > t2_abs) { in dhcvp6_update_deadlines()
134 iface->config.dhcpv6.t2 = t2_abs; in dhcvp6_update_deadlines()
137 if (iface->config.dhcpv6.expire < expire_abs) { in dhcvp6_update_deadlines()
138 iface->config.dhcpv6.expire = expire_abs; in dhcvp6_update_deadlines()
146 NET_DBG("sched dhcpv6 timeout iface=%p timeout=%llums", iface, timeout); in dhcpv6_set_timeout()
148 if (u64_add_overflow(now, timeout, &iface->config.dhcpv6.timeout)) { in dhcpv6_set_timeout()
149 iface->config.dhcpv6.timeout = UINT64_MAX; in dhcpv6_set_timeout()
162 /* DHCPv6 RFC8415, ch. 15. the randomization factor should be a random in randomize_timeout()
173 /* DHCPv6 RFC8415, ch. 15. Retransmission time for the first msg. */ in dhcpv6_initial_retransmit_time()
182 /* DHCPv6 RFC8415, ch. 15. Retransmission time for the subsequent msg. */ in dhcpv6_next_retransmit_time()
196 /* DHCPv6 packet encoding functions */
494 pkt, &iface->config.dhcpv6.clientid); in dhcpv6_add_options()
502 pkt, &iface->config.dhcpv6.serverid); in dhcpv6_add_options()
510 pkt, iface->config.dhcpv6.exchange_start); in dhcpv6_add_options()
518 .iaid = iface->config.dhcpv6.addr_iaid, in dhcpv6_add_options()
522 memcpy(&ia_na.iaaddr.addr, &iface->config.dhcpv6.addr, in dhcpv6_add_options()
534 .iaid = iface->config.dhcpv6.prefix_iaid, in dhcpv6_add_options()
538 memcpy(&ia_pd.iaprefix.prefix, &iface->config.dhcpv6.prefix, in dhcpv6_add_options()
540 ia_pd.iaprefix.prefix_len = iface->config.dhcpv6.prefix_len; in dhcpv6_add_options()
600 if (dhcpv6_add_header(pkt, msg_type, iface->config.dhcpv6.tid) < 0) { in dhcpv6_create_message()
626 .ia_na = iface->config.dhcpv6.params.request_addr, in dhcpv6_send_solicit()
627 .ia_pd = iface->config.dhcpv6.params.request_prefix, in dhcpv6_send_solicit()
652 .ia_na = iface->config.dhcpv6.params.request_addr, in dhcpv6_send_request()
653 .ia_pd = iface->config.dhcpv6.params.request_prefix, in dhcpv6_send_request()
678 .ia_na = iface->config.dhcpv6.params.request_addr, in dhcpv6_send_renew()
679 .iaaddr = iface->config.dhcpv6.params.request_addr, in dhcpv6_send_renew()
680 .ia_pd = iface->config.dhcpv6.params.request_prefix, in dhcpv6_send_renew()
681 .iaprefix = iface->config.dhcpv6.params.request_prefix, in dhcpv6_send_renew()
705 .ia_na = iface->config.dhcpv6.params.request_addr, in dhcpv6_send_rebind()
706 .iaaddr = iface->config.dhcpv6.params.request_addr, in dhcpv6_send_rebind()
707 .ia_pd = iface->config.dhcpv6.params.request_prefix, in dhcpv6_send_rebind()
708 .iaprefix = iface->config.dhcpv6.params.request_prefix, in dhcpv6_send_rebind()
749 /* DHCPv6 packet parsing functions */
860 /* DHCPv6 RFC8415, ch. 21.6 The client MUST discard any addresses for in dhcpv6_parse_option_iaaddr()
938 /* DHCPv6 RFC8415, ch. 21.4 If a client receives an IA_NA with T1 in dhcpv6_parse_option_ia_na()
1036 /* DHCPv6 RFC8415, ch. 21.22 The client MUST discard any prefixes for in dhcpv6_parse_option_iaprefix()
1114 /* DHCPv6 RFC8415, ch. 21.21 If a client receives an IA_PD with T1 in dhcpv6_parse_option_ia_pd()
1259 * DHCPv6 RFC8415, ch. 18.2.1. in dhcpv6_find_server_preference()
1319 * DHCPv6 RFC8415, ch. 21.13. in dhcpv6_find_status_code()
1330 /* DHCPv6 state changes */
1346 iface->config.dhcpv6.retransmit_timeout = in dhcpv6_enter_soliciting()
1348 iface->config.dhcpv6.retransmissions = 0; in dhcpv6_enter_soliciting()
1349 iface->config.dhcpv6.server_preference = -1; in dhcpv6_enter_soliciting()
1350 iface->config.dhcpv6.exchange_start = k_uptime_get(); in dhcpv6_enter_soliciting()
1353 dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); in dhcpv6_enter_soliciting()
1358 iface->config.dhcpv6.retransmit_timeout = in dhcpv6_enter_requesting()
1360 iface->config.dhcpv6.retransmissions = 0; in dhcpv6_enter_requesting()
1361 iface->config.dhcpv6.exchange_start = k_uptime_get(); in dhcpv6_enter_requesting()
1364 dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); in dhcpv6_enter_requesting()
1369 iface->config.dhcpv6.retransmit_timeout = in dhcpv6_enter_renewing()
1371 iface->config.dhcpv6.retransmissions = 0; in dhcpv6_enter_renewing()
1372 iface->config.dhcpv6.exchange_start = k_uptime_get(); in dhcpv6_enter_renewing()
1375 dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); in dhcpv6_enter_renewing()
1380 iface->config.dhcpv6.retransmit_timeout = in dhcpv6_enter_rebinding()
1382 iface->config.dhcpv6.retransmissions = 0; in dhcpv6_enter_rebinding()
1383 iface->config.dhcpv6.exchange_start = k_uptime_get(); in dhcpv6_enter_rebinding()
1386 dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); in dhcpv6_enter_rebinding()
1391 iface->config.dhcpv6.retransmit_timeout = in dhcpv6_enter_confirming()
1393 iface->config.dhcpv6.retransmissions = 0; in dhcpv6_enter_confirming()
1394 iface->config.dhcpv6.exchange_start = k_uptime_get(); in dhcpv6_enter_confirming()
1397 dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); in dhcpv6_enter_confirming()
1402 iface->config.dhcpv6.timeout = iface->config.dhcpv6.t1; in dhcpv6_enter_bound()
1405 &iface->config.dhcpv6, in dhcpv6_enter_bound()
1406 sizeof(iface->config.dhcpv6)); in dhcpv6_enter_bound()
1411 iface->config.dhcpv6.state = state; in dhcpv6_enter_state()
1414 net_dhcpv6_state_name(iface->config.dhcpv6.state)); in dhcpv6_enter_state()
1416 switch (iface->config.dhcpv6.state) { in dhcpv6_enter_state()
1445 /* DHCPv6 input processing */
1457 if (iface->config.dhcpv6.state != NET_DHCPV6_SOLICITING) { in dhcpv6_handle_advertise()
1468 if (iface->config.dhcpv6.clientid.length != duid.length || in dhcpv6_handle_advertise()
1469 memcmp(&iface->config.dhcpv6.clientid.duid, &duid.duid, in dhcpv6_handle_advertise()
1470 iface->config.dhcpv6.clientid.length) != 0) { in dhcpv6_handle_advertise()
1484 if (memcmp(iface->config.dhcpv6.tid, tid, in dhcpv6_handle_advertise()
1485 sizeof(iface->config.dhcpv6.tid)) != 0) { in dhcpv6_handle_advertise()
1509 if ((int16_t)server_preference < iface->config.dhcpv6.server_preference) { in dhcpv6_handle_advertise()
1515 if (iface->config.dhcpv6.params.request_addr) { in dhcpv6_handle_advertise()
1530 if (iface->config.dhcpv6.params.request_prefix) { in dhcpv6_handle_advertise()
1545 memcpy(&iface->config.dhcpv6.serverid, &duid, in dhcpv6_handle_advertise()
1546 sizeof(iface->config.dhcpv6.serverid)); in dhcpv6_handle_advertise()
1547 iface->config.dhcpv6.server_preference = server_preference; in dhcpv6_handle_advertise()
1549 /* DHCPv6 RFC8415, ch. 18.2.1, if client received Advertise in dhcpv6_handle_advertise()
1555 iface->config.dhcpv6.retransmissions > 0) { in dhcpv6_handle_advertise()
1575 if (iface->config.dhcpv6.state != NET_DHCPV6_REQUESTING && in dhcpv6_handle_reply()
1576 iface->config.dhcpv6.state != NET_DHCPV6_CONFIRMING && in dhcpv6_handle_reply()
1577 iface->config.dhcpv6.state != NET_DHCPV6_RENEWING && in dhcpv6_handle_reply()
1578 iface->config.dhcpv6.state != NET_DHCPV6_REBINDING) { in dhcpv6_handle_reply()
1589 if (iface->config.dhcpv6.clientid.length != duid.length || in dhcpv6_handle_reply()
1590 memcmp(&iface->config.dhcpv6.clientid.duid, &duid.duid, in dhcpv6_handle_reply()
1591 iface->config.dhcpv6.clientid.length) != 0) { in dhcpv6_handle_reply()
1605 if (memcmp(iface->config.dhcpv6.tid, tid, in dhcpv6_handle_reply()
1606 sizeof(iface->config.dhcpv6.tid)) != 0) { in dhcpv6_handle_reply()
1624 /* DHCPv6 RFC8415, ch. 18.2.10.1. If the client receives a NotOnLink in dhcpv6_handle_reply()
1631 if (iface->config.dhcpv6.state == NET_DHCPV6_REQUESTING && in dhcpv6_handle_reply()
1640 if (iface->config.dhcpv6.state == NET_DHCPV6_CONFIRMING) { in dhcpv6_handle_reply()
1649 if (iface->config.dhcpv6.params.request_addr) { in dhcpv6_handle_reply()
1656 if (iface->config.dhcpv6.addr_iaid != ia_na.iaid) { in dhcpv6_handle_reply()
1662 if (iface->config.dhcpv6.params.request_prefix) { in dhcpv6_handle_reply()
1669 if (iface->config.dhcpv6.prefix_iaid != ia_pd.iaid) { in dhcpv6_handle_reply()
1675 iface->config.dhcpv6.t1 = UINT64_MAX; in dhcpv6_handle_reply()
1676 iface->config.dhcpv6.t2 = UINT64_MAX; in dhcpv6_handle_reply()
1677 iface->config.dhcpv6.expire = now; in dhcpv6_handle_reply()
1679 if (iface->config.dhcpv6.params.request_addr) { in dhcpv6_handle_reply()
1686 net_if_ipv6_addr_rm(iface, &iface->config.dhcpv6.addr); in dhcpv6_handle_reply()
1687 memset(&iface->config.dhcpv6.addr, 0, sizeof(struct in6_addr)); in dhcpv6_handle_reply()
1694 if (!net_ipv6_addr_cmp(&iface->config.dhcpv6.addr, in dhcpv6_handle_reply()
1696 !net_ipv6_addr_cmp(&iface->config.dhcpv6.addr, in dhcpv6_handle_reply()
1699 net_if_ipv6_addr_rm(iface, &iface->config.dhcpv6.addr); in dhcpv6_handle_reply()
1702 memcpy(&iface->config.dhcpv6.addr, &ia_na.iaaddr.addr, in dhcpv6_handle_reply()
1703 sizeof(iface->config.dhcpv6.addr)); in dhcpv6_handle_reply()
1715 NET_ERR("Failed to configure DHCPv6 address"); in dhcpv6_handle_reply()
1722 if (iface->config.dhcpv6.params.request_prefix) { in dhcpv6_handle_reply()
1729 net_if_ipv6_prefix_rm(iface, &iface->config.dhcpv6.prefix, in dhcpv6_handle_reply()
1730 iface->config.dhcpv6.prefix_len); in dhcpv6_handle_reply()
1731 memset(&iface->config.dhcpv6.prefix, 0, sizeof(struct in6_addr)); in dhcpv6_handle_reply()
1732 iface->config.dhcpv6.prefix_len = 0; in dhcpv6_handle_reply()
1737 if (!net_ipv6_addr_cmp(&iface->config.dhcpv6.prefix, in dhcpv6_handle_reply()
1739 (!net_ipv6_addr_cmp(&iface->config.dhcpv6.prefix, in dhcpv6_handle_reply()
1741 iface->config.dhcpv6.prefix_len != ia_pd.iaprefix.prefix_len)) { in dhcpv6_handle_reply()
1743 net_if_ipv6_prefix_rm(iface, &iface->config.dhcpv6.prefix, in dhcpv6_handle_reply()
1744 iface->config.dhcpv6.prefix_len); in dhcpv6_handle_reply()
1747 iface->config.dhcpv6.prefix_len = ia_pd.iaprefix.prefix_len; in dhcpv6_handle_reply()
1749 memcpy(&iface->config.dhcpv6.prefix, &ia_pd.iaprefix.prefix, in dhcpv6_handle_reply()
1750 sizeof(iface->config.dhcpv6.prefix)); in dhcpv6_handle_reply()
1763 NET_ERR("Failed to configure DHCPv6 prefix"); in dhcpv6_handle_reply()
1831 NET_DBG("Received DHCPv6 packet [type=%d, tid=0x%02x%02x%02x]", in dhcpv6_input()
1870 /* DHCPv6 timer management */
1874 uint64_t timeout = iface->config.dhcpv6.timeout; in dhcpv6_timeleft()
1888 net_dhcpv6_state_name(iface->config.dhcpv6.state), timeleft); in dhcpv6_manage_timers()
1891 return iface->config.dhcpv6.timeout; in dhcpv6_manage_timers()
1901 switch (iface->config.dhcpv6.state) { in dhcpv6_manage_timers()
1908 if (iface->config.dhcpv6.params.request_addr && in dhcpv6_manage_timers()
1909 !net_ipv6_addr_cmp(&iface->config.dhcpv6.addr, in dhcpv6_manage_timers()
1914 if (iface->config.dhcpv6.params.request_prefix && in dhcpv6_manage_timers()
1915 !net_ipv6_addr_cmp(&iface->config.dhcpv6.prefix, in dhcpv6_manage_timers()
1920 if ((have_addr || have_prefix) && now < iface->config.dhcpv6.expire) { in dhcpv6_manage_timers()
1925 iface->config.dhcpv6.expire = now + DHCPV6_CNF_MAX_RD; in dhcpv6_manage_timers()
1927 if (!iface->config.dhcpv6.params.request_prefix) { in dhcpv6_manage_timers()
1936 return iface->config.dhcpv6.timeout; in dhcpv6_manage_timers()
1939 if (iface->config.dhcpv6.server_preference >= 0) { in dhcpv6_manage_timers()
1941 return iface->config.dhcpv6.timeout; in dhcpv6_manage_timers()
1944 iface->config.dhcpv6.retransmissions++; in dhcpv6_manage_timers()
1945 iface->config.dhcpv6.retransmit_timeout = in dhcpv6_manage_timers()
1947 iface->config.dhcpv6.retransmit_timeout, in dhcpv6_manage_timers()
1951 dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); in dhcpv6_manage_timers()
1953 return iface->config.dhcpv6.timeout; in dhcpv6_manage_timers()
1955 if (iface->config.dhcpv6.retransmissions >= DHCPV6_REQ_MAX_RC) { in dhcpv6_manage_timers()
1958 return iface->config.dhcpv6.timeout; in dhcpv6_manage_timers()
1961 iface->config.dhcpv6.retransmissions++; in dhcpv6_manage_timers()
1962 iface->config.dhcpv6.retransmit_timeout = in dhcpv6_manage_timers()
1964 iface->config.dhcpv6.retransmit_timeout, in dhcpv6_manage_timers()
1968 dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); in dhcpv6_manage_timers()
1970 return iface->config.dhcpv6.timeout; in dhcpv6_manage_timers()
1972 if (now >= iface->config.dhcpv6.expire) { in dhcpv6_manage_timers()
1974 return iface->config.dhcpv6.timeout; in dhcpv6_manage_timers()
1977 iface->config.dhcpv6.retransmissions++; in dhcpv6_manage_timers()
1978 iface->config.dhcpv6.retransmit_timeout = in dhcpv6_manage_timers()
1980 iface->config.dhcpv6.retransmit_timeout, in dhcpv6_manage_timers()
1984 dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); in dhcpv6_manage_timers()
1986 if (iface->config.dhcpv6.timeout > iface->config.dhcpv6.expire) { in dhcpv6_manage_timers()
1987 iface->config.dhcpv6.timeout = iface->config.dhcpv6.expire; in dhcpv6_manage_timers()
1990 return iface->config.dhcpv6.timeout; in dhcpv6_manage_timers()
1992 if (now >= iface->config.dhcpv6.t2) { in dhcpv6_manage_timers()
1994 return iface->config.dhcpv6.timeout; in dhcpv6_manage_timers()
1997 iface->config.dhcpv6.retransmissions++; in dhcpv6_manage_timers()
1998 iface->config.dhcpv6.retransmit_timeout = in dhcpv6_manage_timers()
2000 iface->config.dhcpv6.retransmit_timeout, in dhcpv6_manage_timers()
2004 dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); in dhcpv6_manage_timers()
2006 if (iface->config.dhcpv6.timeout > iface->config.dhcpv6.t2) { in dhcpv6_manage_timers()
2007 iface->config.dhcpv6.timeout = iface->config.dhcpv6.t2; in dhcpv6_manage_timers()
2010 return iface->config.dhcpv6.timeout; in dhcpv6_manage_timers()
2012 if (now >= iface->config.dhcpv6.expire) { in dhcpv6_manage_timers()
2014 return iface->config.dhcpv6.timeout; in dhcpv6_manage_timers()
2017 iface->config.dhcpv6.retransmissions++; in dhcpv6_manage_timers()
2018 iface->config.dhcpv6.retransmit_timeout = in dhcpv6_manage_timers()
2020 iface->config.dhcpv6.retransmit_timeout, in dhcpv6_manage_timers()
2024 dhcpv6_set_timeout(iface, iface->config.dhcpv6.retransmit_timeout); in dhcpv6_manage_timers()
2026 if (iface->config.dhcpv6.timeout > iface->config.dhcpv6.expire) { in dhcpv6_manage_timers()
2027 iface->config.dhcpv6.timeout = iface->config.dhcpv6.expire; in dhcpv6_manage_timers()
2030 return iface->config.dhcpv6.timeout; in dhcpv6_manage_timers()
2035 return iface->config.dhcpv6.timeout; in dhcpv6_manage_timers()
2053 CONTAINER_OF(current, struct net_if_config, dhcpv6), in dhcpv6_timeout()
2085 if (node == &iface->config.dhcpv6.node) { in dhcpv6_iface_event_handler()
2111 struct net_dhcpv6_duid_storage *clientid = &iface->config.dhcpv6.clientid; in dhcpv6_generate_client_duid()
2124 /* DHCPv6 public API */
2130 if (iface->config.dhcpv6.state != NET_DHCPV6_DISABLED) { in net_dhcpv6_start()
2131 NET_ERR("DHCPv6 already running on iface %p, state %s", iface, in net_dhcpv6_start()
2132 net_dhcpv6_state_name(iface->config.dhcpv6.state)); in net_dhcpv6_start()
2143 NET_DBG("Starting DHCPv6 on iface %p", iface); in net_dhcpv6_start()
2145 iface->config.dhcpv6.params = *params; in net_dhcpv6_start()
2151 sys_slist_append(&dhcpv6_ifaces, &iface->config.dhcpv6.node); in net_dhcpv6_start()
2154 iface->config.dhcpv6.addr_iaid = net_if_get_by_iface(iface); in net_dhcpv6_start()
2158 iface->config.dhcpv6.prefix_iaid = net_if_get_by_iface(iface); in net_dhcpv6_start()
2173 switch (iface->config.dhcpv6.state) { in net_dhcpv6_stop()
2175 NET_INFO("DHCPv6 already disabled on iface %p", iface); in net_dhcpv6_stop()
2186 NET_DBG("Stopping DHCPv6 on iface %p, state %s", iface, in net_dhcpv6_stop()
2187 net_dhcpv6_state_name(iface->config.dhcpv6.state)); in net_dhcpv6_stop()
2192 &iface->config.dhcpv6.node); in net_dhcpv6_stop()
2209 struct net_dhcpv6_params params = iface->config.dhcpv6.params; in net_dhcpv6_restart()