Skip to content
Permalink
Browse files

net: if: Add syscall interface to IP address add and rm

Make IPv4 and IPv6 address addition and removal possible from
userspace app. But allow this only if CONFIG_NET_IF_USERSPACE_ACCESS
By default these operations are not allowed from userspace app.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
  • Loading branch information...
jukkar committed May 29, 2019
1 parent 0ca1aaa commit 041cd5f18ffb7339110ce08944bf31e9bd8ee1e8
Showing with 257 additions and 0 deletions.
  1. +73 −0 include/net/net_if.h
  2. +8 −0 subsys/net/ip/Kconfig
  3. +176 −0 subsys/net/ip/net_if.c
@@ -840,6 +840,16 @@ struct net_if_addr *net_if_ipv6_addr_lookup(const struct in6_addr *addr,
struct net_if_addr *net_if_ipv6_addr_lookup_by_iface(struct net_if *iface,
struct in6_addr *addr);

/**
* @brief Check if this IPv6 address belongs to one of the interface indices.
*
* @param addr IPv6 address
*
* @return >0 if address was found in given network interface index,
* all other values mean address was not found
*/
__syscall int net_if_ipv6_addr_lookup_by_index(const struct in6_addr *addr);

/**
* @brief Add a IPv6 address to an interface
*
@@ -855,6 +865,21 @@ struct net_if_addr *net_if_ipv6_addr_add(struct net_if *iface,
enum net_addr_type addr_type,
u32_t vlifetime);

/**
* @brief Add a IPv6 address to an interface by index
*
* @param index Network interface index
* @param addr IPv6 address
* @param addr_type IPv6 address type
* @param vlifetime Validity time for this address
*
* @return True if ok, false if address could not be added
*/
__syscall bool net_if_ipv6_addr_add_by_index(int index,
struct in6_addr *addr,
enum net_addr_type addr_type,
u32_t vlifetime);

/**
* @brief Update validity lifetime time of an IPv6 address.
*
@@ -874,6 +899,16 @@ void net_if_ipv6_addr_update_lifetime(struct net_if_addr *ifaddr,
*/
bool net_if_ipv6_addr_rm(struct net_if *iface, const struct in6_addr *addr);

/**
* @brief Remove an IPv6 address from an interface by index
*
* @param index Network interface index
* @param addr IPv6 address
*
* @return True if successfully removed, false otherwise
*/
__syscall bool net_if_ipv6_addr_rm_by_index(int index,
const struct in6_addr *addr);

/**
* @brief Add a IPv6 multicast address to an interface
@@ -1443,6 +1478,42 @@ struct net_if_addr *net_if_ipv4_addr_add(struct net_if *iface,
*/
bool net_if_ipv4_addr_rm(struct net_if *iface, struct in_addr *addr);

/**
* @brief Check if this IPv4 address belongs to one of the interface indices.
*
* @param addr IPv4 address
*
* @return >0 if address was found in given network interface index,
* all other values mean address was not found
*/
__syscall int net_if_ipv4_addr_lookup_by_index(const struct in_addr *addr);

/**
* @brief Add a IPv4 address to an interface by network interface index
*
* @param index Network interface index
* @param addr IPv4 address
* @param addr_type IPv4 address type
* @param vlifetime Validity time for this address
*
* @return True if ok, false if the address could not be added
*/
__syscall bool net_if_ipv4_addr_add_by_index(int index,
struct in_addr *addr,
enum net_addr_type addr_type,
u32_t vlifetime);

/**
* @brief Remove a IPv4 address from an interface by interface index
*
* @param index Network interface index
* @param addr IPv4 address
*
* @return True if successfully removed, false otherwise
*/
__syscall bool net_if_ipv4_addr_rm_by_index(int index,
const struct in_addr *addr);

/**
* @brief Add a IPv4 multicast address to an interface
*
@@ -2026,6 +2097,8 @@ struct net_if_api {
}
#endif

#include <syscalls/net_if.h>

/**
* @}
*/
@@ -492,6 +492,14 @@ config NET_HEADERS_ALWAYS_CONTIGUOUS
NET_BUF_FIXED_DATA_SIZE enabled and NET_BUF_DATA_SIZE of 128 for
instance.

config NET_IF_USERSPACE_ACCESS
bool "Allow userspace app to manipulate network interface"
depends on USERSPACE
help
Only enable this if you want a userspace application to manipulate
network interface. Currently this is limited to add or remove
IP addresses. By default this is not allowed.

choice
prompt "Default Network Interface"
default NET_DEFAULT_IF_FIRST
@@ -10,6 +10,7 @@ LOG_MODULE_REGISTER(net_if, CONFIG_NET_IF_LOG_LEVEL);
#include <init.h>
#include <kernel.h>
#include <linker/sections.h>
#include <syscall_handler.h>
#include <stdlib.h>
#include <string.h>
#include <net/net_core.h>
@@ -751,6 +752,30 @@ struct net_if_addr *net_if_ipv6_addr_lookup_by_iface(struct net_if *iface,
return NULL;
}

int z_impl_net_if_ipv6_addr_lookup_by_index(const struct in6_addr *addr)
{
struct net_if *iface = NULL;
struct net_if_addr *if_addr;

if_addr = net_if_ipv6_addr_lookup(addr, &iface);
if (!if_addr) {
return 0;
}

return net_if_get_by_iface(iface);
}

#ifdef CONFIG_USERSPACE
Z_SYSCALL_HANDLER(net_if_ipv6_addr_lookup_by_index, addr)
{
struct in6_addr addr_v6;

Z_OOPS(z_user_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6)));

return z_impl_net_if_ipv6_addr_lookup_by_index(&addr_v6);
}
#endif

#if defined(CONFIG_NET_IPV6)
static bool check_timeout(u32_t start, s32_t timeout, u32_t counter,
u32_t current_time)
@@ -1087,6 +1112,69 @@ bool net_if_ipv6_addr_rm(struct net_if *iface, const struct in6_addr *addr)
return false;
}

bool z_impl_net_if_ipv6_addr_add_by_index(int index,
struct in6_addr *addr,
enum net_addr_type addr_type,
u32_t vlifetime)
{
struct net_if *iface;

iface = net_if_get_by_index(index);
if (!iface) {
return false;
}

return net_if_ipv6_addr_add(iface, addr, addr_type, vlifetime) ?
true : false;
}

#ifdef CONFIG_USERSPACE
Z_SYSCALL_HANDLER(net_if_ipv6_addr_add_by_index, index, addr, addr_type,
vlifetime)
{
#if defined(CONFIG_NET_IF_USERSPACE_ACCESS)
struct in6_addr addr_v6;

Z_OOPS(z_user_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6)));

return z_impl_net_if_ipv6_addr_add_by_index(index,
&addr_v6,
addr_type,
vlifetime);
#else
return false;
#endif /* CONFIG_NET_IF_USERSPACE_ACCESS */
}
#endif /* CONFIG_USERSPACE */

bool z_impl_net_if_ipv6_addr_rm_by_index(int index,
const struct in6_addr *addr)
{
struct net_if *iface;

iface = net_if_get_by_index(index);
if (!iface) {
return false;
}

return net_if_ipv6_addr_rm(iface, addr);
}

#ifdef CONFIG_USERSPACE
Z_SYSCALL_HANDLER(net_if_ipv6_addr_rm_by_index, index, addr)
{
#if defined(CONFIG_NET_IF_USERSPACE_ACCESS)
struct in6_addr addr_v6;

Z_OOPS(z_user_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6)));

return z_impl_net_if_ipv6_addr_rm_by_index(index, &addr_v6);
#else
return false;
#endif /* CONFIG_NET_IF_USERSPACE_ACCESS */
}
#endif /* CONFIG_USERSPACE */

struct net_if_mcast_addr *net_if_ipv6_maddr_add(struct net_if *iface,
const struct in6_addr *addr)
{
@@ -2485,6 +2573,30 @@ struct net_if_addr *net_if_ipv4_addr_lookup(const struct in_addr *addr,
return NULL;
}

int z_impl_net_if_ipv4_addr_lookup_by_index(const struct in_addr *addr)
{
struct net_if_addr *if_addr;
struct net_if *iface = NULL;

if_addr = net_if_ipv4_addr_lookup(addr, &iface);
if (!if_addr) {
return 0;
}

return net_if_get_by_iface(iface);
}

#ifdef CONFIG_USERSPACE
Z_SYSCALL_HANDLER(net_if_ipv4_addr_lookup_by_index, addr)
{
struct in_addr addr_v4;

Z_OOPS(z_user_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4)));

return z_impl_net_if_ipv4_addr_lookup_by_index(&addr_v4);
}
#endif

#if defined(CONFIG_NET_IPV4)
static struct net_if_addr *ipv4_addr_find(struct net_if *iface,
struct in_addr *addr)
@@ -2609,6 +2721,70 @@ bool net_if_ipv4_addr_rm(struct net_if *iface, struct in_addr *addr)
return false;
}

bool z_impl_net_if_ipv4_addr_add_by_index(int index,
struct in_addr *addr,
enum net_addr_type addr_type,
u32_t vlifetime)
{
struct net_if *iface;
struct net_if_addr *if_addr;

iface = net_if_get_by_index(index);
if (!iface) {
return false;
}

if_addr = net_if_ipv4_addr_add(iface, addr, addr_type, vlifetime);
return if_addr ? true : false;
}

#ifdef CONFIG_USERSPACE
Z_SYSCALL_HANDLER(net_if_ipv4_addr_add_by_index, index, addr, addr_type,
vlifetime)
{
#if defined(CONFIG_NET_IF_USERSPACE_ACCESS)
struct in_addr addr_v4;

Z_OOPS(z_user_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4)));

return z_impl_net_if_ipv4_addr_add_by_index(index,
&addr_v4,
addr_type,
vlifetime);
#else
return false;
#endif /* CONFIG_NET_IF_USERSPACE_ACCESS */
}
#endif /* CONFIG_USERSPACE */

bool z_impl_net_if_ipv4_addr_rm_by_index(int index,
const struct in_addr *addr)
{
struct net_if *iface;

iface = net_if_get_by_index(index);
if (!iface) {
return false;
}

return net_if_ipv4_addr_rm(iface, addr);
}

#ifdef CONFIG_USERSPACE
Z_SYSCALL_HANDLER(net_if_ipv4_addr_rm_by_index, index, addr)
{
#if defined(CONFIG_NET_IF_USERSPACE_ACCESS)
struct in_addr addr_v4;

Z_OOPS(z_user_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4)));

return (uint32_t)z_impl_net_if_ipv4_addr_rm_by_index(index, &addr_v4);
#else
return false;
#endif /* CONFIG_NET_IF_USERSPACE_ACCESS */
}
#endif /* CONFIG_USERSPACE */

#if defined(CONFIG_NET_IPV4)
static struct net_if_mcast_addr *ipv4_maddr_find(struct net_if *iface,
bool is_used,

0 comments on commit 041cd5f

Please sign in to comment.
You can’t perform that action at this time.