Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sys/net/sock_util: don't require interface for link-local addr if there is only a single interface #17927

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions sys/include/net/netif.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 15 additions & 0 deletions sys/net/netif/netif.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
15 changes: 15 additions & 0 deletions sys/net/sock/sock_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why checking again for netif_iter(netif) != NULL ? According to doc netif_iter returns NULL, if there is no interface after @p last, which would be already true for the first call of netif_iter.

Copy link
Contributor Author

@benpicco benpicco Apr 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • netif_iter(NULL) gives the first interface
  • netif_iter(netif_iter(NULL)) gives the second interface
  • and so on

This should only set the interface if there is a first, but not a second interface. (to mirror the behavior of netutils_get_ipv6())

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;
Expand Down Expand Up @@ -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);
benpicco marked this conversation as resolved.
Show resolved Hide resolved
}
return 0;
}
#endif
Expand Down
25 changes: 25 additions & 0 deletions tests/netutils/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
Expand Down