net: if: Add functions to loop over IPv4/IPv6 addresses

Add new net_if API functions which allow to loop over all valid
IPv4/IPv6 addresses assigned to the interface and execute a callback
function on them.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
Robert Lubos 2023-07-17 15:12:36 +02:00 committed by Carles Cufí
parent f0958c62e4
commit b2314c8362
2 changed files with 94 additions and 0 deletions

View file

@ -1209,6 +1209,29 @@ bool net_if_ipv6_addr_rm(struct net_if *iface, const struct in6_addr *addr);
__syscall bool net_if_ipv6_addr_rm_by_index(int index,
const struct in6_addr *addr);
/**
* @typedef net_if_ip_addr_cb_t
* @brief Callback used while iterating over network interface IP addresses
*
* @param iface Pointer to the network interface the address belongs to
* @param addr Pointer to current IP address
* @param user_data A valid pointer to user data or NULL
*/
typedef void (*net_if_ip_addr_cb_t)(struct net_if *iface,
struct net_if_addr *addr,
void *user_data);
/**
* @brief Go through all IPv6 addresses on a network interface and call callback
* for each used address.
*
* @param iface Pointer to the network interface
* @param cb User-supplied callback function to call
* @param user_data User specified data
*/
void net_if_ipv6_addr_foreach(struct net_if *iface, net_if_ip_addr_cb_t cb,
void *user_data);
/**
* @brief Add a IPv6 multicast address to an interface
*
@ -1840,6 +1863,17 @@ __syscall bool net_if_ipv4_addr_add_by_index(int index,
__syscall bool net_if_ipv4_addr_rm_by_index(int index,
const struct in_addr *addr);
/**
* @brief Go through all IPv4 addresses on a network interface and call callback
* for each used address.
*
* @param iface Pointer to the network interface
* @param cb User-supplied callback function to call
* @param user_data User specified data
*/
void net_if_ipv4_addr_foreach(struct net_if *iface, net_if_ip_addr_cb_t cb,
void *user_data);
/**
* @brief Add a IPv4 multicast address to an interface
*

View file

@ -1982,6 +1982,36 @@ bool z_vrfy_net_if_ipv6_addr_rm_by_index(int index,
#include <syscalls/net_if_ipv6_addr_rm_by_index_mrsh.c>
#endif /* CONFIG_USERSPACE */
void net_if_ipv6_addr_foreach(struct net_if *iface, net_if_ip_addr_cb_t cb,
void *user_data)
{
struct net_if_ipv6 *ipv6;
if (iface == NULL) {
return;
}
net_if_lock(iface);
ipv6 = iface->config.ip.ipv6;
if (ipv6 == NULL) {
goto out;
}
for (int i = 0; i < NET_IF_MAX_IPV6_ADDR; i++) {
struct net_if_addr *if_addr = &ipv6->unicast[i];
if (!if_addr->is_used) {
continue;
}
cb(iface, if_addr, user_data);
}
out:
net_if_unlock(iface);
}
struct net_if_mcast_addr *net_if_ipv6_maddr_add(struct net_if *iface,
const struct in6_addr *addr)
{
@ -3784,6 +3814,36 @@ bool z_vrfy_net_if_ipv4_addr_rm_by_index(int index,
#include <syscalls/net_if_ipv4_addr_rm_by_index_mrsh.c>
#endif /* CONFIG_USERSPACE */
void net_if_ipv4_addr_foreach(struct net_if *iface, net_if_ip_addr_cb_t cb,
void *user_data)
{
struct net_if_ipv4 *ipv4;
if (iface == NULL) {
return;
}
net_if_lock(iface);
ipv4 = iface->config.ip.ipv4;
if (ipv4 == NULL) {
goto out;
}
for (int i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) {
struct net_if_addr *if_addr = &ipv4->unicast[i];
if (!if_addr->is_used) {
continue;
}
cb(iface, if_addr, user_data);
}
out:
net_if_unlock(iface);
}
static struct net_if_mcast_addr *ipv4_maddr_find(struct net_if *iface,
bool is_used,
const struct in_addr *addr)