@@ -57,6 +57,11 @@ typedef struct ipv6_interface_route_on_link_t {
5757 ns_list_link_t link ;
5858} ipv6_interface_route_on_link_t ;
5959
60+ typedef struct ipv6_interface_dns_server_on_link_t {
61+ uint8_t addr [16 ]; /*!< DNS Server IPv6 address */
62+ ns_list_link_t link ;
63+ } ipv6_interface_dns_server_on_link_t ;
64+
6065#define WB_UPDATE_PERIOD_SECONDS 23
6166
6267#define ROUTER_SOL_MAX_COUNTER 4
@@ -77,6 +82,14 @@ static NS_LIST_DEFINE(prefix_on_link, ipv6_interface_prefix_on_link_t, link);
7782static NS_LIST_DEFINE (route_on_link , ipv6_interface_route_on_link_t , link ) ;
7883static prefix_list_t ipv6_prefixs = NS_LIST_INIT (ipv6_prefixs );
7984
85+
86+ /*Router advertisement daemon configurations*/
87+ static uint16_t radv_default_route_lifetime = 0 ;
88+ static NS_LIST_DEFINE (dns_server_list , ipv6_interface_dns_server_on_link_t , link ) ;
89+
90+ static uint16_t dns_search_list_len = 0 ;
91+ static uint8_t * dns_search_list_ptr = NULL ;
92+
8093bool tunnel_in_use = false;
8194
8295static void ethernet_data_conf_cb (const eth_mac_api_t * api , const eth_data_conf_t * data )
@@ -426,6 +439,73 @@ void ipv6_stack_route_advert_update(uint8_t *address, uint8_t prefixLength, uint
426439 }
427440}
428441
442+ void ipv6_stack_route_advert_default_route (struct protocol_interface_info_entry * cur , bool enable )
443+ {
444+ if (enable ) {
445+ radv_default_route_lifetime = icmpv6_radv_max_rtr_adv_interval (cur ) * 2 / 10 ;
446+ } else {
447+ radv_default_route_lifetime = 0 ;
448+ }
449+ }
450+
451+ int8_t ipv6_stack_route_advert_dns_server_add (uint8_t * address )
452+ {
453+
454+ if (!address ) {
455+ return -1 ;
456+ }
457+
458+ ns_list_foreach (ipv6_interface_dns_server_on_link_t , cur_server , & dns_server_list ) {
459+ if (memcmp (cur_server -> addr , address , 16 ) == 0 ) {
460+ return 0 ;
461+ }
462+ }
463+ ipv6_interface_dns_server_on_link_t * new_entry = ns_dyn_mem_alloc (sizeof (ipv6_interface_dns_server_on_link_t ));
464+ if (!new_entry ) {
465+ return -1 ;
466+ }
467+ memcpy (new_entry -> addr , address , 16 );
468+ ns_list_add_to_end (& dns_server_list , new_entry );
469+ return 0 ;
470+ }
471+
472+ void ipv6_stack_route_advert_dns_server_delete (uint8_t * address )
473+ {
474+ /* If Address is NULL everything is cleared.
475+ * */
476+ ns_list_foreach_safe (ipv6_interface_dns_server_on_link_t , cur_server , & dns_server_list ) {
477+ if (!address || memcmp (cur_server -> addr , address , 16 ) == 0 ) {
478+ ns_list_remove (& dns_server_list , cur_server );
479+ ns_dyn_mem_free (cur_server );
480+ }
481+ }
482+ }
483+
484+ int8_t ipv6_stack_route_advert_dns_search_list_add (uint8_t * data , uint16_t data_len , uint32_t lifetime )
485+ {
486+
487+ if (dns_search_list_ptr ) {
488+ ns_dyn_mem_free (dns_search_list_ptr );
489+ dns_search_list_ptr = NULL ;
490+ dns_search_list_len = 0 ;
491+ }
492+
493+ // Check if this is delete operation
494+ if (lifetime == 0 || data_len == 0 || data == NULL ) {
495+ return 0 ;
496+ }
497+
498+ dns_search_list_len = ((data_len / 8 ) + 1 ) * 8 ; //Should have padding to 8 bytes
499+ dns_search_list_ptr = ns_dyn_mem_alloc (dns_search_list_len );
500+ if (!dns_search_list_ptr ) {
501+ return -1 ;
502+ }
503+
504+ memset (dns_search_list_ptr , 0 , dns_search_list_len );
505+ memcpy (dns_search_list_ptr , data , data_len );
506+ return 0 ;
507+ }
508+
429509void ipv6_prefix_on_link_update (uint8_t * address )
430510{
431511 protocol_interface_info_entry_t * cur = nwk_interface_get_ipv6_ptr ();
@@ -630,6 +710,7 @@ int8_t ipv6_interface_down(protocol_interface_info_entry_t *cur)
630710 icmpv6_prefix_list_free (& ipv6_prefixs );
631711 ipv6_prefix_online_list_free ();
632712 ipv6_rote_advert_list_free ();
713+ ipv6_stack_route_advert_dns_server_delete (NULL );
633714 neighbor_cache_flush (& cur -> neigh_cache );
634715 ipv6_route_table_remove_interface (cur -> id );
635716 protocol_core_interface_info_reset (cur );
@@ -661,6 +742,12 @@ void ipv6_nd_ra_advert(protocol_interface_info_entry_t *cur, const uint8_t *dest
661742 uint16_t length = 12 + 8 + 16 ;
662743 length += 32 * ns_list_count (& ipv6_prefixs );
663744 length += 32 * ns_list_count (& prefix_on_link );
745+ if (ns_list_count (& dns_server_list )) {
746+ length += 8 + 16 * ns_list_count (& dns_server_list );
747+ }
748+ if (dns_search_list_len ) {
749+ length += 8 + dns_search_list_len ;
750+ }
664751
665752 ns_list_foreach (ipv6_interface_route_on_link_t , tmp_route , & route_on_link ) {
666753 if (tmp_route -> prefix_len < 65 ) {
@@ -680,7 +767,7 @@ void ipv6_nd_ra_advert(protocol_interface_info_entry_t *cur, const uint8_t *dest
680767 * ptr ++ = cur -> adv_cur_hop_limit ;
681768 * ptr ++ = cur -> rtr_adv_flags ;
682769 //Do not advertise default route: set Router Lifetime to 0
683- ptr = common_write_16_bit (0 , ptr );
770+ ptr = common_write_16_bit (radv_default_route_lifetime , ptr );
684771 ptr = common_write_32_bit (cur -> adv_reachable_time , ptr );
685772 ptr = common_write_32_bit (cur -> adv_retrans_timer , ptr );
686773
@@ -749,6 +836,34 @@ void ipv6_nd_ra_advert(protocol_interface_info_entry_t *cur, const uint8_t *dest
749836 }
750837 }
751838
839+ if (ns_list_count (& dns_server_list )) {
840+ * ptr ++ = ICMPV6_OPT_RECURSIVE_DNS_SERVER ;
841+ * ptr ++ = 1 + 2 * ns_list_count (& dns_server_list ); // length is multiples of 8
842+ * ptr ++ = 0 ; // Reserved
843+ * ptr ++ = 0 ; // Reserved
844+ /* RFC8106 The value of Lifetime SHOULD by default be at least 3 * MaxRtrAdvInterval
845+ *
846+ * Lifetimes are short so we dont support removing entries by setting the lifetime 0
847+ * Lifetime is also for all entries so no maintenance is possible
848+ */
849+ ptr = common_write_32_bit (icmpv6_radv_max_rtr_adv_interval (cur ) * 3 / 10 , ptr );
850+
851+ ns_list_foreach_safe (ipv6_interface_dns_server_on_link_t , dns , & dns_server_list ) {
852+ memcpy (ptr , dns -> addr , 16 );
853+ ptr += 16 ;
854+ }
855+ }
856+
857+ if (dns_search_list_ptr && dns_search_list_len > 0 ) {
858+ * ptr ++ = ICMPV6_OPT_DNS_SEARCH_LIST ;
859+ * ptr ++ = 1 + dns_search_list_len / 8 ; // length is multiples of 8
860+ * ptr ++ = 0 ; // Reserved
861+ * ptr ++ = 0 ; // Reserved
862+ ptr = common_write_32_bit (icmpv6_radv_max_rtr_adv_interval (cur ) * 3 / 10 , ptr );
863+ memcpy (ptr , dns_search_list_ptr , dns_search_list_len );
864+ ptr += dns_search_list_len ;
865+ }
866+
752867 buffer_data_end_set (buf , ptr );
753868 memcpy (buf -> dst_sa .address , dest , 16 );
754869 /* Source must be LL address (even if non-LL dest) */
0 commit comments