From a6c5eae1a0424e2202c86faa954d2b7a3c38e954 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 13 Apr 2022 11:56:49 +0200 Subject: [PATCH 1/3] sys/net/sock_util: don't require interface if there is only a single one When the sock_tl_str2ep() function is supplied with a link-local address but no interface, if there is only a single interface use that instead of not setting the interface. --- sys/net/sock/sock_util.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sys/net/sock/sock_util.c b/sys/net/sock/sock_util.c index f47ba2aaaeb6..8833c9810e4c 100644 --- a/sys/net/sock/sock_util.c +++ b/sys/net/sock/sock_util.c @@ -188,6 +188,17 @@ int _parse_netif(sock_udp_ep_t *ep_out, char *netifstart) return (netifend - netifstart); } +static int _get_default_netif(sock_udp_ep_t *ep_out) +{ + netif_t *netif = netif_iter(NULL); + if (netif == NULL || netif_iter(netif) != NULL) { + return -EINVAL; + } + + ep_out->netif = netif_get_id(netif); + return 0; +} + int sock_tl_str2ep(struct _sock_tl_ep *ep_out, const char *str) { unsigned brackets_flag; @@ -251,6 +262,10 @@ int sock_tl_str2ep(struct _sock_tl_ep *ep_out, const char *str) #ifdef SOCK_HAS_IPV6 if (inet_pton(AF_INET6, hostbuf, ep_out->addr.ipv6) == 1) { ep_out->family = AF_INET6; + if (*hostend != '%' && + ipv6_addr_is_link_local((ipv6_addr_t *)ep_out->addr.ipv6)) { + return _get_default_netif(ep_out); + } return 0; } #endif From 87f0c6f4b92a6dffef086b56b55fd72dde8af66a Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 19 Apr 2022 18:12:44 +0200 Subject: [PATCH 2/3] net/netif: add netif_unregister() --- sys/include/net/netif.h | 11 +++++++++++ sys/net/netif/netif.c | 15 +++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/sys/include/net/netif.h b/sys/include/net/netif.h index 2316695fa33f..86d452a2b4b4 100644 --- a/sys/include/net/netif.h +++ b/sys/include/net/netif.h @@ -200,6 +200,17 @@ int netif_set_opt(netif_t *netif, netopt_t opt, uint16_t context, */ int netif_register(netif_t *netif); +/** + * @brief Removes a network interface in the global interface list. + * + * @param[in] netif Interface to be removed + * + * @return 0 on success + * @return -EINVAL if @p netif is NULL + * or not part of the global interface list + */ +int netif_unregister(netif_t *netif); + #ifdef __cplusplus } #endif diff --git a/sys/net/netif/netif.c b/sys/net/netif/netif.c index 57064d05d7bf..a4611301b7ae 100644 --- a/sys/net/netif/netif.c +++ b/sys/net/netif/netif.c @@ -36,6 +36,21 @@ int netif_register(netif_t *netif) return 0; } +int netif_unregister(netif_t *netif) +{ + void *found; + + if (netif == NULL) { + return -EINVAL; + } + + unsigned state = irq_disable(); + found = list_remove(&netif_list, &netif->node); + irq_restore(state); + + return found ? 0 : -EINVAL; +} + netif_t *netif_iter(const netif_t *last) { if (last == NULL) { From cf3cbce4825ef9ec9ca2696396f3dc9d8d6ccb07 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 19 Apr 2022 18:13:28 +0200 Subject: [PATCH 3/3] tests/netutils: add test with a single interface --- tests/netutils/main.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/netutils/main.c b/tests/netutils/main.c index d207e4bf5e5d..e58b4531d8c6 100644 --- a/tests/netutils/main.c +++ b/tests/netutils/main.c @@ -232,6 +232,30 @@ static void test_sock_tl_name2ep__name_only(void) TEST_ASSERT(ipv6_addr_equal(&a, (ipv6_addr_t *)&ep.addr.ipv6)); } +static void test_sock_tl_name2ep__ip_if_port_single_netif(void) +{ + static const ipv6_addr_t a = { { + 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff + } + }; + struct _sock_tl_ep ep; + + /* we want to test default netif assignment with a single interface */ + for (unsigned i = 0; i < ARRAY_SIZE(dummy_netif) - 1; --i) { + netif_unregister(&dummy_netif[0].netif); + } + + int res = sock_tl_name2ep(&ep, "[fe80::f8f9:fafb:fcfd:feff]:1234"); + TEST_ASSERT_EQUAL_INT(res, 0); + TEST_ASSERT_EQUAL_INT(AF_INET6, ep.family); + TEST_ASSERT_EQUAL_INT(1234, ep.port); + TEST_ASSERT_EQUAL_INT(1, ep.netif); + TEST_ASSERT(ipv6_addr_equal(&a, (ipv6_addr_t *)&ep.addr.ipv6)); + + netif_register(&dummy_netif[0].netif); +} + Test *tests_netutils_ipv6_tests(void) { for (unsigned i = 0; i < ARRAY_SIZE(dummy_netif); ++i) { @@ -253,6 +277,7 @@ Test *tests_netutils_ipv6_tests(void) new_TestFixture(test_sock_tl_name2ep__ip_if_port), new_TestFixture(test_sock_tl_name2ep__name_port), new_TestFixture(test_sock_tl_name2ep__name_only), + new_TestFixture(test_sock_tl_name2ep__ip_if_port_single_netif), }; EMB_UNIT_TESTCALLER(ipv6_addr_tests, NULL, NULL, fixtures);