@@ -47,7 +47,7 @@ static const char test_str_all_tx_bufs[] =
4747#define MY_IPV4_ADDR "127.0.0.1"
4848#define MY_IPV6_ADDR "::1"
4949#define MY_MCAST_IPV4_ADDR "224.0.0.1"
50- #define MY_MCAST_IPV6_ADDR "ff00 ::1"
50+ #define MY_MCAST_IPV6_ADDR "ff01 ::1"
5151
5252#define ANY_PORT 0
5353#define SERVER_PORT 4242
@@ -947,6 +947,8 @@ static struct in6_addr my_addr1 = { { { 0x20, 0x01, 0x0d, 0xb8, 1, 0, 0, 0,
947947static struct in_addr my_addr2 = { { { 192 , 0 , 2 , 2 } } };
948948static struct in6_addr my_addr3 = { { { 0x20 , 0x01 , 0x0d , 0xb8 , 1 , 0 , 0 , 0 ,
949949 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x3 } } };
950+ static struct in6_addr my_mcast_addr1 = { { { 0xff , 0x01 , 0 , 0 , 0 , 0 , 0 , 0 ,
951+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x1 } } };
950952static uint8_t server_lladdr [] = { 0x01 , 0x02 , 0x03 , 0xff , 0xfe ,
951953 0x04 , 0x05 , 0x06 };
952954static struct net_linkaddr server_link_addr = {
@@ -957,6 +959,7 @@ static struct net_linkaddr server_link_addr = {
957959#define PEER_IPV6_ADDR_ETH "2001:db8:100::2"
958960#define TEST_TXTIME INT64_MAX
959961#define WAIT_TIME K_MSEC(250)
962+ #define WAIT_TIME_LONG K_MSEC(1000)
960963
961964static void eth_fake_iface_init (struct net_if * iface )
962965{
@@ -1015,6 +1018,7 @@ static void iface_cb(struct net_if *iface, void *user_data)
10151018
10161019 if (net_if_l2 (iface ) == & NET_L2_GET_NAME (DUMMY )) {
10171020 lo0 = iface ;
1021+ net_if_set_default (iface );
10181022 }
10191023}
10201024
@@ -2531,6 +2535,142 @@ ZTEST(net_socket_udp, test_37_ipv6_src_addr_select)
25312535 & my_addr3 , & dest );
25322536}
25332537
2538+ ZTEST (net_socket_udp , test_38_ipv6_multicast_ifindex )
2539+ {
2540+ struct sockaddr_in6 saddr6 = {
2541+ .sin6_family = AF_INET6 ,
2542+ .sin6_port = htons (SERVER_PORT ),
2543+ .sin6_addr = my_mcast_addr1 ,
2544+ };
2545+ struct net_if_mcast_addr * ifmaddr ;
2546+ struct net_if_addr * ifaddr ;
2547+ int server_sock ;
2548+ size_t addrlen ;
2549+ size_t optlen ;
2550+ int ifindex ;
2551+ int optval ;
2552+ int sock ;
2553+ int ret ;
2554+ int err ;
2555+
2556+ net_if_foreach (iface_cb , & eth_iface );
2557+ zassert_not_null (eth_iface , "No ethernet interface found" );
2558+
2559+ ifmaddr = net_if_ipv6_maddr_add (eth_iface , & my_mcast_addr1 );
2560+ if (!ifmaddr ) {
2561+ DBG ("Cannot add IPv6 multicast address %s\n" ,
2562+ net_sprint_ipv6_addr (& my_mcast_addr1 ));
2563+ zassert_not_null (ifmaddr , "mcast_addr1" );
2564+ }
2565+
2566+ ifaddr = net_if_ipv6_addr_add (eth_iface , & my_addr3 ,
2567+ NET_ADDR_AUTOCONF , 0 );
2568+ if (!ifaddr ) {
2569+ DBG ("Cannot add IPv6 address %s\n" ,
2570+ net_sprint_ipv6_addr (& my_addr3 ));
2571+ zassert_not_null (ifaddr , "addr1" );
2572+ }
2573+
2574+ net_if_up (eth_iface );
2575+
2576+ /* Check that we get the default interface */
2577+ sock = zsock_socket (AF_INET6 , SOCK_DGRAM , IPPROTO_UDP );
2578+ zassert_true (sock >= 0 , "Cannot create socket (%d)" , - errno );
2579+
2580+ optval = 0 ; optlen = 0U ;
2581+ ret = zsock_getsockopt (sock , IPPROTO_IPV6 , IPV6_MULTICAST_IF ,
2582+ & optval , & optlen );
2583+ zexpect_equal (ret , 0 , "setsockopt failed (%d)" , errno );
2584+ zexpect_equal (optlen , sizeof (optval ), "invalid optlen %d vs %d" ,
2585+ optlen , sizeof (optval ));
2586+ ifindex = net_if_get_by_iface (net_if_get_default ());
2587+ zexpect_equal (optval , ifindex ,
2588+ "getsockopt multicast ifindex (expected %d got %d)" ,
2589+ ifindex , optval );
2590+
2591+ ret = zsock_close (sock );
2592+ zassert_equal (sock , 0 , "Cannot close socket (%d)" , - errno );
2593+
2594+ /* Check failure for IPv4 socket */
2595+ sock = zsock_socket (AF_INET , SOCK_DGRAM , IPPROTO_UDP );
2596+ zassert_true (sock >= 0 , "Cannot create socket (%d)" , - errno );
2597+
2598+ optval = 0 ; optlen = 0U ;
2599+ ret = zsock_getsockopt (sock , IPPROTO_IPV6 , IPV6_MULTICAST_IF ,
2600+ & optval , & optlen );
2601+ err = - errno ;
2602+ zexpect_equal (ret , -1 , "setsockopt failed (%d)" , errno );
2603+ zexpect_equal (err , - EAFNOSUPPORT , "setsockopt failed (%d)" , errno );
2604+ zexpect_equal (optlen , 0U , "setsockopt optlen (%d)" , optlen );
2605+
2606+ ret = zsock_close (sock );
2607+ zassert_equal (sock , 0 , "Cannot close socket (%d)" , - errno );
2608+
2609+ /* Check that we can set the interface */
2610+ sock = zsock_socket (AF_INET6 , SOCK_DGRAM , IPPROTO_UDP );
2611+ zassert_true (sock >= 0 , "Cannot create socket (%d)" , - errno );
2612+
2613+ /* Clear any existing interface value by setting it to 0 */
2614+ optval = 0 ; optlen = sizeof (int );
2615+ ret = zsock_setsockopt (sock , IPPROTO_IPV6 , IPV6_MULTICAST_IF ,
2616+ & optval , optlen );
2617+ err = - errno ;
2618+ zexpect_equal (ret , 0 , "setsockopt failed (%d)" , err );
2619+ zexpect_equal (optlen , sizeof (optval ), "invalid optlen %d vs %d" ,
2620+ optlen , sizeof (optval ));
2621+
2622+ /* Set the output multicast packet interface to the default interface */
2623+ optval = net_if_get_by_iface (net_if_get_default ()); optlen = sizeof (int );
2624+ ret = zsock_setsockopt (sock , IPPROTO_IPV6 , IPV6_MULTICAST_IF ,
2625+ & optval , optlen );
2626+ zexpect_equal (ret , 0 , "setsockopt failed (%d)" , errno );
2627+ zexpect_equal (optlen , sizeof (optval ), "invalid optlen %d vs %d" ,
2628+ optlen , sizeof (optval ));
2629+
2630+ optval = 0 ; optlen = 0U ;
2631+ ret = zsock_getsockopt (sock , IPPROTO_IPV6 , IPV6_MULTICAST_IF ,
2632+ & optval , & optlen );
2633+ err = - errno ;
2634+ zexpect_equal (ret , 0 , "setsockopt failed (%d)" , err );
2635+ zexpect_equal (optlen , sizeof (int ), "setsockopt optlen (%d)" , optlen );
2636+ zexpect_equal (optval , net_if_get_by_iface (net_if_get_default ()),
2637+ "getsockopt multicast ifindex (expected %d got %d)" ,
2638+ net_if_get_by_iface (net_if_get_default ()), optval );
2639+
2640+ server_sock = prepare_listen_sock_udp_v6 (& saddr6 );
2641+ zassert_not_equal (server_sock , -1 , "Cannot create server socket (%d)" , - errno );
2642+
2643+ test_started = true;
2644+ loopback_enable_address_swap (false);
2645+
2646+ ret = zsock_sendto (sock , TEST_STR_SMALL , sizeof (TEST_STR_SMALL ) - 1 , 0 ,
2647+ (struct sockaddr * )& saddr6 , sizeof (saddr6 ));
2648+ zexpect_equal (ret , STRLEN (TEST_STR_SMALL ),
2649+ "invalid send len (was %d expected %d) (%d)" ,
2650+ ret , STRLEN (TEST_STR_SMALL ), - errno );
2651+
2652+ /* Test that the sent data is received from default interface and
2653+ * not the Ethernet one.
2654+ */
2655+ addrlen = sizeof (saddr6 );
2656+ ret = zsock_recvfrom (server_sock , rx_buf , sizeof (rx_buf ),
2657+ 0 , (struct sockaddr * )& saddr6 , & addrlen );
2658+ zexpect_true (ret >= 0 , "recvfrom fail" );
2659+ zexpect_equal (ret , strlen (TEST_STR_SMALL ),
2660+ "unexpected received bytes" );
2661+ zexpect_mem_equal (rx_buf , TEST_STR_SMALL , sizeof (TEST_STR_SMALL ) - 1 ,
2662+ "wrong data" );
2663+
2664+ ret = zsock_close (sock );
2665+ zassert_equal (ret , 0 , "Cannot close socket (%d)" , - errno );
2666+
2667+ ret = zsock_close (server_sock );
2668+ zassert_equal (ret , 0 , "Cannot close socket (%d)" , - errno );
2669+
2670+ test_started = false;
2671+ loopback_enable_address_swap (true);
2672+ }
2673+
25342674static void after (void * arg )
25352675{
25362676 ARG_UNUSED (arg );
0 commit comments